Опечатки ЛР № 16

This commit is contained in:
Eugene8388608
2025-06-15 14:01:23 +00:00
parent af6c6134cc
commit ce734ac765

View File

@@ -1,4 +1,4 @@
# Лабораторная работа №16 "Оценка производительности" # Лабораторная работа № 16 "Оценка производительности"
## Материал для подготовки к лабораторной работе ## Материал для подготовки к лабораторной работе
@@ -22,7 +22,7 @@
Для подсчета производительности, coremark опирается на функцию, возвращающую текущее время, поэтому для оценки производительности нам потребуется вспомогательное периферийное устройство: таймер. Для подсчета производительности, coremark опирается на функцию, возвращающую текущее время, поэтому для оценки производительности нам потребуется вспомогательное периферийное устройство: таймер.
Для вывода результатов тестирования, необходимо описать способ, которым coremark сможет выводить очередной символ сообщения — для этого мы будем использовать контроллер UART из ЛР13. Для вывода результатов тестирования, необходимо описать способ, которым coremark сможет выводить очередной символ сообщения — для этого мы будем использовать контроллер UART из ЛР  13.
Кроме того, скомпилированная без оптимизаций программа будет занимать чуть более 32KiB, поэтому нам потребуется изменить размер памяти инструкций. Кроме того, скомпилированная без оптимизаций программа будет занимать чуть более 32KiB, поэтому нам потребуется изменить размер памяти инструкций.
@@ -34,7 +34,7 @@
1. Реализовать модуль-контроллер "таймер". 1. Реализовать модуль-контроллер "таймер".
2. Подключить этот модуль к системной шине. 2. Подключить этот модуль к системной шине.
2.1. В случае, если до этого в ЛР13 вашим устройством вывода было не UART TX, вам необходимо подключить к системной шине готовый модуль [uart_tx_sb_ctrl](../Made-up%20modules/lab_13.uart_tx_sb_ctrl.sv). 1. В случае, если до этого в ЛР  13 вашим устройством вывода было не UART TX, вам необходимо подключить к системной шине готовый модуль [uart_tx_sb_ctrl](../Made-up%20modules/lab_13.uart_tx_sb_ctrl.sv).
3. Добавить реализацию платформозависимых функций программы coremark. 3. Добавить реализацию платформозависимых функций программы coremark.
4. Скомпилировать программу. 4. Скомпилировать программу.
5. Изменить размер памяти инструкций. 5. Изменить размер памяти инструкций.
@@ -61,7 +61,7 @@
|0x14 | RW | [0:2³²-1] | Указание количества повторений генерации прерываний | |0x14 | RW | [0:2³²-1] | Указание количества повторений генерации прерываний |
|0x24 | W | 1 | Программный сброс | |0x24 | W | 1 | Программный сброс |
_Таблица 1. Адресное пространство _Таблица 1. Адресное пространство контроллера таймера._
Прототип модуля представлен в _листинге 1_. Прототип модуля представлен в _листинге 1_.
@@ -86,7 +86,7 @@ module timer_sb_ctrl(
); );
``` ```
_Листинг 1. Прототип таймера._ _Листинг 1. Прототип контроллера таймера._
Обратите внимание, что у модуля нет сигнала `interrupt_return_i`. Модуль будет генерировать прерывания ровно на 1 такт. Если процессор в этот момент не будет готов обработать прерывания (обрабатывая в этот момент какой-либо другой перехват) — запрос будет сразу же пропущен и таймер начнет отсчитывать следующий. Обратите внимание, что у модуля нет сигнала `interrupt_return_i`. Модуль будет генерировать прерывания ровно на 1 такт. Если процессор в этот момент не будет готов обработать прерывания (обрабатывая в этот момент какой-либо другой перехват) — запрос будет сразу же пропущен и таймер начнет отсчитывать следующий.
@@ -106,13 +106,13 @@ logic [63:0] system_counter_at_start;
- `OFF` — отключен (не генерирует прерывания) - `OFF` — отключен (не генерирует прерывания)
- `NTIMES` — включен до тех пор, пока не сгенерирует N прерываний (значение N хранится в регистре `repeat_counter` и обновляется после каждого сгенерированного прерывания). После генерации N прерываний, переходит в режим `OFF`. - `NTIMES` — включен до тех пор, пока не сгенерирует N прерываний (значение N хранится в регистре `repeat_counter` и обновляется после каждого сгенерированного прерывания). После генерации N прерываний, переходит в режим `OFF`.
- `FOREVER` — бесконечная генерация прерываний. Не отключится, пока режим работы прерываний не будет изменен. - `FOREVER` — бесконечная генерация прерываний. Не отключится, пока режим работы прерываний не будет изменен.
- `next_mode` — комбинационный сигнал, который подается на вход записи в регистр `mode` (аналог `next_state` из ЛР15). Данный сигнал меняется только запросами на запись по адресу `0x10` или в случае, если `repeat_counter == 0` в режиме `NTIMES`. Поскольку этому сигналу можно присваивать только сигналы того же типа (`mode`/`next_mode`), либо константы из перечисления, запросы на запись можно реализовать через блок `case` (где перебираются 3 возможных значения `write_data_i`). - `next_mode` — комбинационный сигнал, который подается на вход записи в регистр `mode` (аналог `next_state` из ЛР  15). Данный сигнал меняется только запросами на запись по адресу `0x10` или в случае, если `repeat_counter == 0` в режиме `NTIMES`. Поскольку этому сигналу можно присваивать только сигналы того же типа (`mode`/`next_mode`), либо константы из перечисления, запросы на запись можно реализовать через блок `case` (где перебираются 3 возможных значения `write_data_i`).
- `repeat_counter` — регистр, ассоциированный с адресом `0x14`. Количество повторений для режима `NTIMES`. Уменьшается в момент генерации прерывания в этом режиме в случае, если еще не равен нулю. - `repeat_counter` — регистр, ассоциированный с адресом `0x14`. Количество повторений для режима `NTIMES`. Уменьшается в момент генерации прерывания в этом режиме в случае, если еще не равен нулю.
- `system_counter_at_start` — неархитектурный регистр, хранящий значение системного счётчика на момент начала отсчета таймера. Обновляется при генерации прерывания (если это не последнее прерывание в режиме `NTIMES`) и при запросе на запись в регистр `mode` значения не `OFF`. - `system_counter_at_start` — неархитектурный регистр, хранящий значение системного счётчика на момент начала отсчета таймера. Обновляется при генерации прерывания (если это не последнее прерывание в режиме `NTIMES`) и при запросе на запись в регистр `mode` значения не `OFF`.
Выходной сигнал interrupt_request_o должен быть равен единице, если текущий режим работы не `OFF`, а сумма `system_counter_at_start` и `delay` равна `system_counter`. Выходной сигнал interrupt_request_o должен быть равен единице, если текущий режим работы не `OFF`, а сумма `system_counter_at_start` и `delay` равна `system_counter`.
Для подключения данного таймера к системной шине, мы воспользуемся первым свободным базовым адресом, оставшимся после ЛР13: `0x08`. Таким образом, для обращения к системному счётчику, процессор будет использовать адрес `0x08000000` для обращения к регистру `delay` `0x08000008` и т.п. Для подключения данного таймера к системной шине, мы воспользуемся первым свободным базовым адресом, оставшимся после ЛР  13: `0x08`. Таким образом, для обращения к системному счётчику, процессор будет использовать адрес `0x08000000` для обращения к регистру `delay` `0x08000008` и т.п.
### Настройка Coremark ### Настройка Coremark
@@ -144,7 +144,7 @@ barebones_clock()
_Листинг 2. Код функции `barebones_clock`._ _Листинг 2. Код функции `barebones_clock`._
После ЛР14 вы уже должны представлять, что здесь происходит. Мы создали указатель с абсолютным адресом `0x08000000` — адресом системного счётчика. Разыменование данного указателя вернет текущее значение системного счётчика, что и должно быть результатом вызова этой функции. Поскольку тест закончится менее чем за секунду, не обязательно загружать значение старших 32 бит (они будут не равны нулю только спустя 2³²тактов / 10⁶тактов/с ≈ 429c). После ЛР  14 вы уже должны представлять, что здесь происходит. Мы создали указатель с абсолютным адресом `0x08000000` — адресом системного счётчика. Разыменование данного указателя вернет текущее значение системного счётчика, что и должно быть результатом вызова этой функции. Поскольку тест закончится менее чем за секунду, не обязательно загружать значение старших 32 бит (они будут не равны нулю только спустя 2³² тактов / 10⁶ тактов/с ≈ 429 c).
Для того, чтобы корректно преобразовать тики системного счётчика во время, используется функция [`time_in_secs`](https://github.com/eembc/coremark/blob/d5fad6bd094899101a4e5fd53af7298160ced6ab/barebones/core_portme.c#L117), которая уже реализована, но для работы которой нужно определить макрос `CLOCKS_PER_SEC`, характеризующий тактовую частоту, на которой работает процессор. Давайте определим данный макрос сразу над макросом [`EE_TICKS_PER_SEC`](https://github.com/eembc/coremark/blob/d5fad6bd094899101a4e5fd53af7298160ced6ab/barebones/core_portme.c#L62): Для того, чтобы корректно преобразовать тики системного счётчика во время, используется функция [`time_in_secs`](https://github.com/eembc/coremark/blob/d5fad6bd094899101a4e5fd53af7298160ced6ab/barebones/core_portme.c#L117), которая уже реализована, но для работы которой нужно определить макрос `CLOCKS_PER_SEC`, характеризующий тактовую частоту, на которой работает процессор. Давайте определим данный макрос сразу над макросом [`EE_TICKS_PER_SEC`](https://github.com/eembc/coremark/blob/d5fad6bd094899101a4e5fd53af7298160ced6ab/barebones/core_portme.c#L62):
@@ -176,14 +176,14 @@ uart_send_char(char c)
} }
``` ```
_Листинг 3. Код функции `uart_send_char_`._ _Листинг 3. Код функции `uart_send_char`._
`0x06000000` — базовый адрес контроллера UART TX из ЛР13 (и адрес передаваемых этим контроллером данных). `0x06000000` — базовый адрес контроллера UART TX из ЛР  13 (и адрес передаваемых этим контроллером данных).
`0x08` — смещение до адреса регистра `busy` в адресном пространстве этого контроллера. `0x08` — смещение до адреса регистра `busy` в адресном пространстве этого контроллера.
#### 3. Реализация функции первичной настройки #### 3. Реализация функции первичной настройки
Это функция [`portable_init`](https://github.com/eembc/coremark/blob/d5fad6bd094899101a4e5fd53af7298160ced6ab/barebones/core_portme.c#L130), расположена в уже известном ранее файле [`core_portme`.c]. Данная функция выполняет необходимые нам настройки перед началом теста. Для нас главное — настроить нужным образом контроллер UART. Это функция [`portable_init`](https://github.com/eembc/coremark/blob/d5fad6bd094899101a4e5fd53af7298160ced6ab/barebones/core_portme.c#L130), расположена в уже известном ранее файле [`core_portme.c`]. Данная функция выполняет необходимые нам настройки перед началом теста. Для нас главное — настроить нужным образом контроллер UART.
Допустим мы хотим, чтобы данные передавались на скорости `115200`, c одним стоповым битом и контролем бита четности. В этом случае, мы должны добавить в начало функции следующий код: Допустим мы хотим, чтобы данные передавались на скорости `115200`, c одним стоповым битом и контролем бита четности. В этом случае, мы должны добавить в начало функции следующий код:
```C ```C
@@ -210,7 +210,7 @@ _Листинг 4. Код функции `uart_send_char`._
### Компиляция ### Компиляция
Для компиляции программы, вам потребуются предоставленные файлы [Makefile](Makefile) и [linker_script.ld](linker_script.ld), а также файл [startup.S](../14.%20Programming/startup.S) из ЛР14. Эти файлы необходимо скопировать с заменой в корень папки с программой. Для компиляции программы, вам потребуются предоставленные файлы [Makefile](Makefile) и [linker_script.ld](linker_script.ld), а также файл [startup.S](../14.%20Programming/startup.S) из ЛР  14. Эти файлы необходимо скопировать с заменой в корень папки с программой.
`Makefile` написан из расчёта, что кросс-компилятор расположен по пути `C:/riscv_cc/`. В случае, если это не так, измените первую строчку данного файла в соответствии с расположением кросс-компилятора. `Makefile` написан из расчёта, что кросс-компилятор расположен по пути `C:/riscv_cc/`. В случае, если это не так, измените первую строчку данного файла в соответствии с расположением кросс-компилятора.
@@ -300,7 +300,7 @@ _Листинг 6. Лог вывода результатов coremark. Знач
3. Интегрируйте модуль `timer_sb_ctrl` в процессорную систему. 3. Интегрируйте модуль `timer_sb_ctrl` в процессорную систему.
1. Ко входу `rst_i` модуля подключите сигнал `core_reset_o` программатора. Таким образом, системный счётчик начнет работать только когда память системы будет проинициализирована. 1. Ко входу `rst_i` модуля подключите сигнал `core_reset_o` программатора. Таким образом, системный счётчик начнет работать только когда память системы будет проинициализирована.
2. Сигнал прерывания этого модуля подключать не обязательно, т.к. coremark будет осуществлять чтение путем опроса системного счётчика, а не по прерыванию. 2. Сигнал прерывания этого модуля подключать не обязательно, т.к. coremark будет осуществлять чтение путем опроса системного счётчика, а не по прерыванию.
4. В случае, если до этого в ЛР13 вашим устройством вывода было не UART TX, вам необходимо подключить к системной шине готовый модуль [uart_tx_sb_ctrl](../Made-up%20modules/lab_13.uart_tx_sb_ctrl.sv). 4. В случае, если до этого в ЛР  13 вашим устройством вывода было не UART TX, вам необходимо подключить к системной шине готовый модуль [uart_tx_sb_ctrl](../Made-up%20modules/lab_13.uart_tx_sb_ctrl.sv).
5. Получите исходный код программы coremark. Для этого можно либо склонировать [репозиторий](https://github.com/eembc/coremark/tree/d5fad6bd094899101a4e5fd53af7298160ced6ab), либо скачать его в виде архива. 5. Получите исходный код программы coremark. Для этого можно либо склонировать [репозиторий](https://github.com/eembc/coremark/tree/d5fad6bd094899101a4e5fd53af7298160ced6ab), либо скачать его в виде архива.
6. Добавьте реализацию платформозависимых функций программы coremark. Для этого в папке `barebones` необходимо: 6. Добавьте реализацию платформозависимых функций программы coremark. Для этого в папке `barebones` необходимо:
1. в файле `core_portme.c`: 1. в файле `core_portme.c`:
@@ -318,7 +318,7 @@ _Листинг 6. Лог вывода результатов coremark. Знач
2. В случае, если инициализация будет осуществляться посредством `$readmemh`, не забудьте удалить первую строчку со стартовым адресом из файла, инициализирующего память данных. 2. В случае, если инициализация будет осуществляться посредством `$readmemh`, не забудьте удалить первую строчку со стартовым адресом из файла, инициализирующего память данных.
3. В случае, если инициализация будет осуществляться с помощью программатора, используйте вспомогательные вызовы `program_region` из пакета `bluster_pkg`, как это было сделано в `lab_15_tb_system`. 3. В случае, если инициализация будет осуществляться с помощью программатора, используйте вспомогательные вызовы `program_region` из пакета `bluster_pkg`, как это было сделано в `lab_15_tb_system`.
4. В исходном виде тестбенч описан под инициализацию памяти посредством `$readmemh`. 4. В исходном виде тестбенч описан под инициализацию памяти посредством `$readmemh`.
11. Выполните моделирование системы с помощью модуля [lab_16.tb_coremark](lab_16.tb_coremark). 11. Выполните моделирование системы с помощью модуля [lab_16.tb_coremark.sv](lab_16.tb_coremark.sv).
1. Результаты теста будут выведены приблизительно на `355ms` времени моделирования. 1. Результаты теста будут выведены приблизительно на `355ms` времени моделирования.
## Оценка производительности ## Оценка производительности