WIP: APS cumulative update (#98)

* WIP: APS cumulative update

* Update How FPGA works.md

* Перенос раздела "Последовательностная логика" в отдельный док

* Исправление картинки

* Исправление оформления индексов

* Переработка раздела Vivado Basics

* Добавление картинки в руководство по созданию проекта

* Исправление ссылок в анализе rtl

* Обновление изображения в sequential logic

* Исправление ссылок в bug hunting

* Исправление ссылок

* Рефактор руководства по прошивке ПЛИС

* Mass update

* Update fig_10

* Restore fig_02
This commit is contained in:
Andrei Solodovnikov
2024-09-02 10:20:08 +03:00
committed by GitHub
parent 78bb01ef95
commit a28002e681
195 changed files with 3640 additions and 2664 deletions

View File

@@ -1,15 +1,15 @@
# Лабораторная работа 10 "Подсистема прерывания"
# Лабораторная работа 10 "Подсистема прерывания"
Данная лабораторная работа посвящена изучению систем прерывания в компьютерах и их использованию для обработки программных и аппаратных событий. В процессе работы вы познакомитесь с основными понятиями и принципами работы систем прерывания, а также со средствами программной обработки прерываний.
## Материал для подготовки к лабораторной работе
## Материалы для подготовки к лабораторной работе
- Изучить [теорию по регистрам контроля и статуса](../../Other/CSR.md).
- [Теоретический материал по регистрам контроля и статуса](../../Other/CSR.md).
## Цель
1. Разработать модуль контроллера прерываний.
2. Разработать модуль контроллера регистров статуса и контроля (**CSR**-контроллер).
1. Описать модуль контроллера прерываний.
2. Описать модуль контроллера регистров статуса и контроля (**CSR**-контроллер).
## Ход выполнения
@@ -21,7 +21,7 @@
### Прерывания/Исключения
С компьютером постоянно происходят события, на которые он должен реагировать, запуская соответствующие подпрограммы. Например, при движении мышки нужно перерисовать ее курсор на новом месте или нужно среагировать на подключение флешки и т.п. Возможность запускать нужные подпрограммы в ответ на различные события, возникающие внутри или снаружи компьютера, существенно расширяют его возможности. События, требующие внимания процессора называются **прерываниями** (**interrupt**). Происходящие события формируют запрос на прерывание процессору.
С компьютером постоянно происходят события, на которые он должен реагировать, запуская соответствующие подпрограммы. Например, при движении мышки нужно перерисовать её курсор на новом месте или нужно среагировать на подключение флешки и т.п. Возможность запускать нужные подпрограммы в ответ на различные события, возникающие внутри или снаружи компьютера, существенно расширяют его возможности. События, требующие внимания процессора называются **прерываниями** (**interrupt**). Происходящие события формируют запрос на прерывание процессору.
С.А. Орлов, Б.Я. Цилькер в учебнике "Организация ЭВМ и систем" дают следующее определение системе прерывания:
@@ -29,19 +29,19 @@
Прерывания делятся на **маски́руемые** — которые при желании можно игнорировать (на которые можно наложить [**битовую маску**](https://ru.wikipedia.org/wiki/Битовая_маска), отсюда ударение на второй слог), и **немаски́руемые** — которые игнорировать нельзя (например сбой генератора тактового синхроимпульса в микроконтроллерах семейства PIC24FJ512GU410[[2, стр.130]](https://ww1.microchip.com/downloads/aemDocuments/documents/MCU16/ProductDocuments/DataSheets/PIC24FJ512GU410-Family-Data-Sheet-DS30010203D.pdf)). Прерывание похоже на незапланированный вызов функции, вследствие события в аппаратном обеспечении. Программа (функция), запускаемая в ответ на прерывание, называется **обработчиком прерывания**.
События могут быть не только аппаратными, но и программными синхронными. Такие события называются **исключениями** (**exception**). Программа может столкнуться с состоянием ошибки, вызванным программным обеспечением, таким как неопределенная инструкция, неподдерживаемая данным процессором, в таком случаях говорят, что возникло исключение. К исключениям также относятся сброс, деление на ноль, переполнение и попытки считывания из несуществующей памяти.
События могут быть не только аппаратными, но и программными синхронными. Такие события называются **исключениями** (**exception**). Программа может столкнуться с состоянием ошибки, вызванным программным обеспечением, таким как неопределённая инструкция, неподдерживаемая данным процессором, в таком случаях говорят, что возникло исключение. К исключениям также относятся сброс, деление на ноль, переполнение и попытки считывания из несуществующей памяти.
Важно понимать, что ни прерывание, ни исключение не являются обязательно чем-то плохим. И то и другое — это всего лишь события. Например, с помощью исключений может осуществляться системные вызовы и передача управления отладчику программы.
Как и любой другой вызов функции, при возникновении прерывания или исключения необходимо сохранить адрес возврата, перейти к программе обработчика, выполнить свою работу, восстановить контекст (не оставить никаких следов работы обработчика прерывания) и вернуться к программе, которую прервали.
Благодаря исключениям можно реализовать имитацию наличия каких-то аппаратных блоков программными средствами. Например, при отсутствии аппаратного умножителя, можно написать программу обработчика исключения неподдерживаемой инструкции умножения, реализующую алгоритм умножения через сложение и сдвиг. Тогда, каждый раз, когда в программе будет попадаться инструкция умножения, будет возникать исключение, приводящее к запуску обработчика, перемножающего числа и размещающего результат в нужные ячейки памяти. После выполнения обработчика управление возвращается программе, которая даже не поймет, что что-то произошло и умножитель «ненастоящий».
Благодаря исключениям можно реализовать имитацию наличия каких-то аппаратных блоков программными средствами. Например, при отсутствии аппаратного умножителя, можно написать программу обработчика исключения неподдерживаемой инструкции умножения, реализующую алгоритм умножения через сложение и сдвиг. Тогда, каждый раз, когда в программе будет попадаться инструкция умножения, будет возникать исключение, приводящее к запуску обработчика, перемножающего числа и размещающего результат в нужные ячейки памяти. После выполнения обработчика управление возвращается программе, которая даже не поймёт, что что-то произошло и умножитель «ненастоящий».
---
На протяжении многих лет, концепция понятия "прерывание" постоянно расширялась. Семейство процессоров 80x86 внесло ещё большую путаницу введя инструкцию `int` (программное прерывание). Многие производители используют такие термины как: **исключение** (_exception_), **ошибка** (_fault_), **отказ** (_abort_), **ловушка** (_trap_) и **прерывание** (_interrupt_), чтобы описать явление, которому посвящена данная лабораторная работа. К несчастью, не существует какого-то чёткого соглашения насчёт этих названий. Разные авторы по-разному приспосабливают эти термины для своего повествования[[3, стр.995](https://flint.cs.yale.edu/cs422/doc/art-of-asm/pdf/CH17.PDF)].
Для того, чтобы постараться избежать путаницы, в данной лабораторной работе мы будем использовать три термина, которые введены в спецификации архитектуры RISC-V[[4, стр.10](https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf)], однако имейте в виду, что за пределами данного практикума и спецификации RISC-V в эти термины могут вкладывать другие смыслы.
Для того, чтобы постараться избежать путаницы, в данной лабораторной работе мы будем использовать три термина, которые введены в спецификации архитектуры RISC-V[[4, стр.18](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/unpriv-isa-asciidoc.pdf)], однако имейте в виду, что за пределами данного практикума и спецификации RISC-V в эти термины могут вкладывать другие смыслы.
Сперва озвучим выдержку из спецификации, а потом дадим этим терминам обывательские определения.
@@ -68,9 +68,9 @@
![../../.pic/Labs/lab_10_irq/fig_01.drawio.svg](../../.pic/Labs/lab_10_irq/fig_01.drawio.svg)
_Рисунок 1. Распределение привилегий по уровням абстракций программного обеспечения [[5, стр.448](https://doi.org/10.1007/978-981-16-9113-3_33)]._
_Рисунок 1. Распределение привилегий по уровням абстракций программного обеспечения [[5](https://doi.org/10.1007/978-981-16-9113-3_33), стр.448], [[6](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/priv-isa-asciidoc.pdf), стр. 8]._
Переключение между этими режимами происходит с помощью исключения, называемого **системный вызов**, и который происходит при выполнении специальной инструкции. Для RISC-V такой инструкцией является **ecall**. Это похоже на вызов подпрограммы, но при системном вызове изменяется режим работы и управление передается операционной системе, которая, по коду в инструкции вызова определяет, что от нее хотят. Например, операционная система может предоставить данные с диска, так как запускаемая программа не имеет никакого представления о том, на какой машине ее запустили, или что используется какая-то конкретная файловая система.
Переключение между этими режимами происходит с помощью исключения, называемого **системный вызов**, и который происходит при выполнении специальной инструкции. Для RISC-V такой инструкцией является **ecall**. Это похоже на вызов подпрограммы, но при системном вызове изменяется режим работы и управление передаётся операционной системе, которая, по коду в инструкции вызова определяет, что от неё хотят. Например, операционная система может предоставить данные с диска, так как запускаемая программа не имеет никакого представления о том, на какой машине её запустили, или что используется какая-то конкретная файловая система.
Системы прерываний имеет ряд характеристик, которые варьируются в зависимости от их реализации. Все системы можно условно разбить на две категории: обзорные (прямые) и векторные.
@@ -95,34 +95,34 @@ _Рисунок 1. Распределение привилегий по уров
|0x341 | MRW | mepc | Регистр, хранящий адрес перехваченной инструкции. |
|0x342 | MRW | mcause | Причина перехвата |
_Таблица 1. Список регистров, подлежащих реализации в рамках лабораторной работы._
_Таблица 1. Список регистров, подлежащих реализации в рамках лабораторной работы [[6](https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf), стр. 17]._
По адресу `0x304` должен располагаться регистр, позволяющий маскировать перехваты. Например, если на 5-ом входе системы прерывания генерируется прерывание, то процессор отреагирует на него только в том случае, если 5-ый бит регистра `mie` будет равен 1. Младшие 16 бит этого регистра спецификация RISC-V отводит под маскирование специальных системных прерываний, который не будут поддерживаться нашим процессором (подробней об этом будет в описании регистра mcause). Поэтому в нашей процессорной системе мы будем использовать только старшие 16 бит регистра `mie`, которые отведены для нужд конкретной платформы.
По адресу `0x304` должен располагаться регистр, позволяющий маскировать перехваты. Например, если на 5-ом входе системы прерывания генерируется прерывание, то процессор отреагирует на него только в том случае, если 5-ый бит регистра `mie` будет равен 1. Младшие 16 бит этого регистра спецификация RISC-V отводит под маскирование специальных системных прерываний [[6](https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf), стр. 36], которые не будут поддерживаться нашим процессором (подробней об этом будет в описании регистра mcause). Поэтому в нашей процессорной системе мы будем использовать только старшие 16 бит регистра `mie`, которые отведены для нужд конкретной платформы.
По адресу `0x305` должен располагаться регистр `mtvec`, который состоит из двух полей: BASE[31:2] и MODE. Поле BASE хранит старшие 30 бит базового адреса обработчика перехвата (поскольку этот адрес должен быть всегда равен четырем, младшие два бита считаются равными нулю). Поле MODE кодирует тип системы прерывания:
По адресу `0x305` должен располагаться регистр `mtvec`, который состоит из двух полей: BASE[31:2] и MODE. Поле BASE хранит старшие 30 бит базового адреса обработчика перехвата (поскольку этот адрес должен быть всегда равен четырём, младшие два бита считаются равными нулю). Поле MODE кодирует тип системы прерывания:
- `MODE == 2'd0` — система прерывания обзорная;
- `MODE == 2'd1` — система прерывания векторная.
![../../.pic/Labs/lab_10_irq/fig_02.png](../../.pic/Labs/lab_10_irq/fig_02.png)
_Рисунок 2. Разделение регистра `mtvec` на поля `BASE` и `MODE`_
_Рисунок 2. Разделение регистра `mtvec` на поля `BASE` и `MODE`[[6](https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf), стр. 34]_
В случае обзорной системы прерывания, любой перехват приводит к загрузке в PC значения базового адреса обработчика перехвата (`PC=BASE`). В векторной системе прерывания исключения обрабатываются таким же способом, как и в обзорной системе, а вот прерывания обрабатываются путем загрузки в PC суммы базового адреса и учетверенного значения причины прерывания (`PC=BASE+4*CAUSE`).
В случае обзорной системы прерывания, любой перехват приводит к загрузке в PC значения базового адреса обработчика перехвата (`PC=BASE`). В векторной системе прерывания исключения обрабатываются таким же способом, как и в обзорной системе, а вот прерывания обрабатываются путём загрузки в PC суммы базового адреса и учетверённого значения причины прерывания (`PC=BASE+4*CAUSE`).
В рамках данной лабораторной работы мы будем реализовывать обзорную систему прерываний. Кроме того, поскольку у обзорной системы прерываний `MODE==0`, что совпадет с тем, что два младших бита базового адреса обработчика перехвата должны быть равны нулю, при перехвате мы можем присваивать программному счетчику значение `mtvec` без каких-либо преобразований.
В рамках данной лабораторной работы мы будем реализовывать обзорную систему прерываний. Кроме того, поскольку у обзорной системы прерываний `MODE==0`, что совпадёт с тем, что два младших бита базового адреса обработчика перехвата должны быть равны нулю, при перехвате мы можем присваивать программному счётчику значение `mtvec` без каких-либо преобразований.
Так как обработчик перехвата будет использовать те же регистры, что и прерванная программа, перед использованием регистрового файла, данные из него необходимо сохранить, разместив их на специальном стеке — стеке прерываний. Адрес начала этого стека хранится в регистре `mscratch`, расположенного по адресу `0x340` и по сути является указателем на верхушку стека прерываний.
Регистр `mepc`, расположенный по адресу `0x341` сохраняет адрес инструкции во время исполнения которой произошел перехват. Это очень важно понимать, при реализации **обработчика исключения** — если в нем не перезаписать этот регистр, по возврату из обработчика **процессор снова окажется на инструкции, которая вызвала исключение**.
Регистр `mepc`, расположенный по адресу `0x341` сохраняет адрес инструкции, во время исполнения которой произошёл перехват [[6](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/priv-isa-asciidoc.pdf), стр. 42]. Это очень важно понимать, при реализации **обработчика исключения** — если в нем не перезаписать этот регистр, по возврату из обработчика **процессор снова окажется на инструкции, которая вызвала исключение**.
То как кодируется причина перехвата в регистре `mcause`, расположенного по адресу `0x342` описано в спецификации привилегированной архитектуры[[6, стр.38]](https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf):
То как кодируется причина перехвата в регистре `mcause`, расположенного по адресу `0x342` описано в спецификации привилегированной архитектуры[[6](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/priv-isa-asciidoc.pdf), стр.43]:
![../../.pic/Labs/lab_10_irq/tab_05.png](../../.pic/Labs/lab_10_irq/tab_05.png)
![../../.pic/Labs/lab_10_irq/tab_02.png](../../.pic/Labs/lab_10_irq/tab_02.png)
_Таблица 2. Кодирование причины перехвата в регистре `mcause`._
Нас интересуют части, выделенные красным. В первую очередь то, как кодируется старший бит регистра `mcause`. Он зависит от типа причины перехвата (`1` в случае прерывания, `0` в случае исключения). Оставшиеся 31 бит регистра отводятся под коды различных причин. Поскольку мы создаем учебный процессор, который не будет использован в реальной жизни, он не будет поддерживать большую часть прерываний/исключений (таких как невыровненный доступ к памяти, таймеры и т.п.). В рамках данного курса мы должны поддерживать исключение по нелегальной инструкции (код 0x02) и должны уметь поддерживать прерывания периферийных устройств (под которые зарезервированы коды начиная с 16-го, именно поэтому мы будем использовать только старшие 16 бит регистра `mie`). В рамках данной лабораторной работы процессор будет поддерживать только один источник прерывания, поэтому для кодирования причины прерывания нам потребуется только первый код из диапазона _"Designated for platform use"_. В случае, если вы захотите расширить количество источников прерываний, вы можете выполнить вспомогательную [лабораторную работу №12](../12.%20Daisy%20chain).
Нас интересуют части , выделенные цветом. В первую очередь то, как кодируется старший бит регистра `mcause` (выделено синим). Он зависит от типа причины перехвата (`1` в случае прерывания, `0` в случае исключения). Оставшиеся 31 бит регистра отводятся под коды различных причин. Поскольку мы создаём учебный процессор, который не будет использован в реальной жизни, он не будет поддерживать большую часть прерываний/исключений (таких как невыровненный доступ к памяти, таймеры и т.п.). В рамках данного курса мы должны поддерживать исключение по нелегальной инструкции (код 0x02, выделено красным) и должны уметь поддерживать прерывания периферийных устройств (под которые зарезервированы коды начиная с 16-го, именно поэтому мы будем использовать только старшие 16 бит регистра `mie`). В рамках данной лабораторной работы процессор будет поддерживать только один источник прерывания, поэтому для кодирования причины прерывания нам потребуется только первый код из диапазона _"Designated for platform use"_ (выделено зелёным). В случае, если вы захотите расширить количество источников прерываний, вы можете выполнить вспомогательную [лабораторную работу №12](../12.%20Daisy%20chain).
Таким образом: в случае если произошло исключение (в связи с нелегальной инструкцией), значение `mcause` должно быть `0x00000002`. Если произошло прерывание, значение `mcause` должно быть `0x80000010`.
@@ -152,9 +152,9 @@ _Таблица 2. Кодирование причины перехвата в
Контроллер прерываний это блок процессора, обеспечивающий взаимодействие с устройствами, запрашивающими прерывания, формирование кода причины прерывания для процессора, маскирование прерываний. В некоторых реализация, контроллер прерываний может реагировать на прерывания в соответствии с приоритетом.
Периферийное устройство, которое может генерировать прерывание, подключается к контроллеру прерывания парой проводов: "запрос на прерывание" (`irq_req_i`) и "прерывание обслужено" (`irq_ret_o`). Предположим, к контроллеру прерываний подключили клавиатуру. Когда на ней нажимают клавишу, код этой клавиши попадает в буферный регистр с дополнительным управляющим битом, выставленным в единицу, который подключен к входу запроса на прерывание. Если прерывание не замаскировано (в нашем процессоре это означает, что нулевой бит регистра `mie` выставлен в 1), то контроллер прерывания сгенерирует код причины прерывания (в нашем случае — это константа `0x80000010`). Кроме этого, контроллер прерывания подаст сигнал `irq_o`, чтобы устройство управления процессора узнало, что произошло прерывание и разрешило обновить содержимое регистра причины `mcause`, сохранило адрес прерванной инструкции в `mepc` и загрузило в `PC` вектор прерывания `mtvec`.
Периферийное устройство, которое может генерировать прерывание, подключается к контроллеру прерывания парой проводов: "запрос на прерывание" (`irq_req_i`) и "прерывание обслужено" (`irq_ret_o`). Предположим, к контроллеру прерываний подключили клавиатуру. Когда на ней нажимают клавишу, код этой клавиши попадает в буферный регистр с дополнительным управляющим битом, выставленным в единицу, который подключён к входу запроса на прерывание. Если прерывание не замаскировано (в нашем процессоре это означает, что нулевой бит регистра `mie` выставлен в 1), то контроллер прерывания сгенерирует код причины прерывания (в нашем случае — это константа `0x80000010`). Кроме этого, контроллер прерывания подаст сигнал `irq_o`, чтобы устройство управления процессора узнало, что произошло прерывание и разрешило обновить содержимое регистра причины `mcause`, сохранило адрес прерванной инструкции в `mepc` и загрузило в `PC` вектор прерывания `mtvec`.
Когда будет выполняться инструкция `mret`, устройство управления подаст сигнал контроллеру прерывания, чтобы тот, в свою очередь, направил его в виде сигнала «прерывание обслужено» для соответствующего устройства. После этого периферийное устройство обязано снять сигнал запроса прерывания хотя бы на один такт. В нашем примере сигнал «прерывание обслужено» может быть подключен непосредственно к сбросу буферного регистра клавиатуры.
Когда будет выполняться инструкция `mret`, устройство управления подаст сигнал контроллеру прерывания, чтобы тот, в свою очередь, направил его в виде сигнала «прерывание обслужено» для соответствующего устройства. После этого периферийное устройство обязано снять сигнал запроса прерывания хотя бы на один такт. В нашем примере сигнал «прерывание обслужено» может быть подключён непосредственно к сбросу буферного регистра клавиатуры.
## Структура разрабатываемых устройств
@@ -168,11 +168,11 @@ _Таблица 2. Кодирование причины перехвата в
_Рисунок 3. Место разрабатываемых блоков в структуре процессора._
Пока что вам нужно реализовать только блоки **irq controller** и **control status registers**, а не саму схему, приведенную выше.
Пока что вам нужно реализовать только блоки **irq controller** и **control status registers**, а не саму схему, приведённую выше.
### CSR-контроллер
Рассмотрим один из возможных вариантов организации блока **Control and Status Registers**. Основная работа по описанию схемы блока состоит в описании мультиплексора и демультиплексора. Мультиплексор подает на выход **read_data_o** значение регистра, который соответствует пришедшему адресу. В свою же очередь, демультиплексор маршрутизирует сигнал разрешения на запись **write_enable_i** (en) на тот же регистр.
Рассмотрим один из возможных вариантов организации блока **Control and Status Registers**. Основная работа по описанию схемы блока состоит в описании мультиплексора и демультиплексора. Мультиплексор подаёт на выход **read_data_o** значение регистра, который соответствует пришедшему адресу. В свою же очередь, демультиплексор маршрутизирует сигнал разрешения на запись **write_enable_i** (en) на тот же регистр.
![../../.pic/Labs/lab_10_irq/fig_04.drawio.svg](../../.pic/Labs/lab_10_irq/fig_04.drawio.svg)
@@ -182,7 +182,7 @@ _Рисунок 4. Структурная схема контроллера CS-
Для реализации мультиплексора на языке описания аппаратуры SystemVerilog можно воспользоваться конструкцией `case` внутри блока **always_comb**. Для реализации демультиплексора также можно использовать `case`, только если при описании мультиплексора в зависимости от управляющего сигнала на один и тот же выход идут разные входы, то при описании демультиплексора все будет наоборот: в зависимости от управляющего сигнала, один и тот же вход будет идти на разные выходы (например, на разные биты многоразрядной шины `enable`).
Мультиплексоры, располагаемые на входах регистров `mepc` и `mcause` нужны, чтобы при возникновении сигнала прерывания сразу же разрешить обновить значение этих регистров значением `pc_i`, на котором произошел перехват и кодом причины происходящего сейчас перехвата.
Мультиплексоры, располагаемые на входах регистров `mepc` и `mcause` нужны, чтобы при возникновении сигнала прерывания сразу же разрешить обновить значение этих регистров значением `pc_i`, на котором произошёл перехват и кодом причины происходящего сейчас перехвата.
### Контроллер прерываний
@@ -201,17 +201,17 @@ _Рисунок 5. Структурная схема контроллера пр
Регистры отслеживания обработки прерывания и исключения нужны для того, чтобы мы могли понимать, что в данный момент процессор уже выполняет обработку прерывания / исключения. В такие моменты (если любой из регистров `exc_h`/`irq_h` содержит значение `1`) все последующие запросы на прерывание игнорируются. За это отвечают вентили И и ИЛИ-НЕ в правом верхнем углу схемы.
Однако возможна ситуация возникновения исключения во время обработки прерывания — в этом случае, оба регистра будут хранить значение `1`. В момент возврата из обработчика, придет сигнал `mret_i`, который в первую очередь сбросит регистр `exc_h` и только если тот равен нулю, сбросит регистр `irq_h`.
Однако возможна ситуация возникновения исключения во время обработки прерывания — в этом случае, оба регистра будут хранить значение `1`. В момент возврата из обработчика, придёт сигнал `mret_i`, который в первую очередь сбросит регистр `exc_h` и только если тот равен нулю, сбросит регистр `irq_h`.
Исключение во время обработки исключения не поддерживается данной микроархитектурой и скорее всего приведет к циклическому вызову обработчика исключения. Поэтому код обработчика исключений должен быть написан с особым вниманием.
Исключение во время обработки исключения не поддерживается данной микроархитектурой и скорее всего приведёт к циклическому вызову обработчика исключения. Поэтому код обработчика исключений должен быть написан с особым вниманием.
Логика установки и сброса регистров `irq_h` и `exc_h` работает следующим образом:
- если сигнал, обозначенный в прямоугольнике как `reset` равен единице, в регистр будет записано значение `0`;
- если сигнал, обозначенный в прямоугольнике как `set` равен единице, в регистр будет записано значение `1`;
- в остальных случах, регистр сохраняет свое значение.
- в остальных случаях, регистр сохраняет своё значение.
Обратите внимание, что логика установки и сброса регистров дает приоритет сбросу, хотя сигнал сброса никогда не придет одновременно с сигналом установки (поскольку инструкция `mret` не генерирует исключение, сигнал `mret_i` никогда не придет одновременно с сигналом `exception_i`, а логика приоритета исключений над прерываниями не даст сигналу `mret` распространиться до регистра `irq_h` одновременно с формированием сигнала `irq_o`).
Обратите внимание, что логика установки и сброса регистров даёт приоритет сбросу, хотя сигнал сброса никогда не придёт одновременно с сигналом установки (поскольку инструкция `mret` не генерирует исключение, сигнал `mret_i` никогда не придёт одновременно с сигналом `exception_i`, а логика приоритета исключений над прерываниями не даст сигналу `mret` распространиться до регистра `irq_h` одновременно с формированием сигнала `irq_o`).
Логика приоритета исключений над прерываниями заключается в том, что сигнал `exception_i` является частью логики обработки вложенных прерываний. Пройдя через два логических ИЛИ и последующий инвертор, этот сигнал обнулит запрос на прерывание на логическом И в правом верхнем углу.
@@ -219,7 +219,7 @@ _Рисунок 5. Структурная схема контроллера пр
## Пример обработки перехвата
Ниже представлен пример программы и обработчика перехватов. Программа начинается с инициализации начальных значений регистров управления, указателя на верхушку стека и глобальную область данных, после чего уходит в бесконечный цикл ничего не делая, до тех пор, пока не произойдет перехват.
В _листинге 1_ представлен пример программы с обработчиком перехватов. Программа начинается с инициализации начальных значений регистров управления, указателя на верхушку стека и глобальную область данных, после чего уходит в бесконечный цикл ничего не делая, до тех пор, пока не произойдёт перехват.
Алгоритм работы обработчика перехвата (`trap handler`) выглядит следующим образом:
@@ -338,7 +338,7 @@ done:
1. Описать на языке SystemVerilog модуль контроллера регистров статуса и контроля (**CSR**-контроллер) со следующим прототипом:
```SystemVerilog
```Verilog
module csr_controller(
input logic clk_i,
@@ -367,7 +367,7 @@ endmodule
2. Описать на языке SystemVerilog модуль контроллера прерываний со следующим прототипом:
```SystemVerilog
```Verilog
module interrupt_controller(
input logic clk_i,
input logic rst_i,
@@ -387,30 +387,21 @@ endmodule
## Порядок выполнения задания
1. Внимательно ознакомьтесь с описанием модуля `csr_controller` и его структурной схемой. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
2. Реализуйте модуль `csr_controller`. Для этого:
1. В `Design Sources` проекта с предыдущих лаб, создайте `SystemVerilog`-файл `csr_controller.sv`.
2. Опишите в нем модуль `csr_controller` с таким же именем и портами, как указано в [задании](#задание).
3. Обратите внимание на наличие импорта пакета `csr_pkg`, данный пакет содержит адреса используемых регистров контроля и статуса, которыми будет удобно пользоваться при реализации модуля.
3. После описания модуля его необходимо проверить с помощью тестового окружения.
1. Тестовое окружение находится [здесь](tb_csr.sv).
2. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md).
3. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (`tb_csr`).
4. **По завершению симуляции убедитесь, что в логе есть сообщение о завершении теста!**
4. Внимательно ознакомьтесь с описанием функционального поведения сигналов `interrupt_controller`, а также его структурной схемой. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
5. Реализуйте модуль `interrupt_controller`. Для этого:
1. В `Design Sources` проекта с предыдущих лаб, создайте `SystemVerilog`-файл `interrupt_controller.sv`.
2. Опишите в нем модуль `interrupt_controller` с таким же именем и портами, как указано в [задании](#задание).
6. После описания модуля его необходимо проверить с помощью тестового окружения.
1. Тестовое окружение находится [здесь](tb_irq.sv).
2. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md).
3. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (`tb_irq`).
4. **По завершению симуляции убедитесь, что в логе есть сообщение о завершении теста!**
2. Добавьте в `Design Sources` проекта файл [сsr_pkg.sv](csr_pkg.sv). Данный файл содержит пакет с адресами регистров контроля и статуса, а также кодами команд для взаимодействия с ними.
3. Опишите модуль `csr_controller` с таким же именем и портами, как указано в задании.
4. Проверьте модуль с помощью верификационного окружения, представленного в файле [`lab_10.tb_csr.sv`](lab_10.tb_csr.sv). В случае, если в TCL-консоли появились сообщения об ошибках, вам необходимо [найти](../../Vivado%20Basics/05.%20Bug%20hunting.md) и исправить их.
1. Перед запуском моделирования, убедитесь, что у вас выбран корректный модуль верхнего уровня в `Simulation Sources`.
5. Внимательно ознакомьтесь с описанием функционального поведения сигналов `interrupt_controller`, а также его структурной схемой. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
6. Опишите модуль `interrupt_controller` с таким же именем и портами, как указано в задании.
7. Проверьте модуль с помощью верификационного окружения, представленного в файле [`lab_10.tb_irq.sv`](lab_10.tb_irq.sv). В случае, если в TCL-консоли появились сообщения об ошибках, вам необходимо [найти](../../Vivado%20Basics/05.%20Bug%20hunting.md) и исправить их.
1. Перед запуском моделирования, убедитесь, что у вас выбран корректный модуль верхнего уровня в `Simulation Sources`.
8. Данная лабораторная работа не предполагает проверки в ПЛИС.
## Список использованной литературы
1. С.А. Орлов, Б.Я. Цилькер / Организация ЭВМ и систем: Учебник для вузов. 2-е изд. / СПб.: Питер, 2011.
2. [PIC24FJ512GU410 Family Data Sheet](https://ww1.microchip.com/downloads/aemDocuments/documents/MCU16/ProductDocuments/DataSheets/PIC24FJ512GU410-Family-Data-Sheet-DS30010203D.pdf)
3. [The Art of Assembly Language](https://flint.cs.yale.edu/cs422/doc/art-of-asm/pdf/)
4. [The RISC-V Instruction Set Manual Volume I: Unprivileged ISA](https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf)
4. [The RISC-V Instruction Set Manual Volume I: Unprivileged ISA](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/unpriv-isa-asciidoc.pdf)
5. [Pillai, V.P., Megalingam, R.K. (2022). System Partitioning with Virtualization for Federated and Distributed Machine Learning on Critical IoT Edge Systems. In: Saraswat, M., Sharma, H., Balachandran, K., Kim, J.H., Bansal, J.C. (eds) Congress on Intelligent Systems. Lecture Notes on Data Engineering and Communications Technologies, vol 111. Springer, Singapore.](https://doi.org/10.1007/978-981-16-9113-3_33)
6. [The RISC-V Instruction Set Manual Volume II: Privileged Architecture](https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf)
6. [The RISC-V Instruction Set Manual Volume II: Privileged Architecture](https://github.com/riscv/riscv-isa-manual/releases/download/20240411/priv-isa-asciidoc.pdf)