From ce734ac76562bac49a26a25ee29d359f0c7ee65a Mon Sep 17 00:00:00 2001 From: Eugene8388608 <15855754+Eugene8388608@users.noreply.github.com> Date: Sun, 15 Jun 2025 14:01:23 +0000 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=BF=D0=B5=D1=87=D0=B0=D1=82=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=9B=D0=A0=20=E2=84=96=2016?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Labs/16. Coremark/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Labs/16. Coremark/README.md b/Labs/16. Coremark/README.md index a23ee60..d395b05 100644 --- a/Labs/16. Coremark/README.md +++ b/Labs/16. Coremark/README.md @@ -1,4 +1,4 @@ -# Лабораторная работа №16 "Оценка производительности" +# Лабораторная работа № 16 "Оценка производительности" ## Материал для подготовки к лабораторной работе @@ -22,7 +22,7 @@ Для подсчета производительности, coremark опирается на функцию, возвращающую текущее время, поэтому для оценки производительности нам потребуется вспомогательное периферийное устройство: таймер. -Для вывода результатов тестирования, необходимо описать способ, которым coremark сможет выводить очередной символ сообщения — для этого мы будем использовать контроллер UART из ЛР№13. +Для вывода результатов тестирования, необходимо описать способ, которым coremark сможет выводить очередной символ сообщения — для этого мы будем использовать контроллер UART из ЛР № 13. Кроме того, скомпилированная без оптимизаций программа будет занимать чуть более 32KiB, поэтому нам потребуется изменить размер памяти инструкций. @@ -34,7 +34,7 @@ 1. Реализовать модуль-контроллер "таймер". 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. 4. Скомпилировать программу. 5. Изменить размер памяти инструкций. @@ -61,7 +61,7 @@ |0x14 | RW | [0:2³²-1] | Указание количества повторений генерации прерываний | |0x24 | W | 1 | Программный сброс | -_Таблица 1. Адресное пространство +_Таблица 1. Адресное пространство контроллера таймера._ Прототип модуля представлен в _листинге 1_. @@ -86,7 +86,7 @@ module timer_sb_ctrl( ); ``` -_Листинг 1. Прототип таймера._ +_Листинг 1. Прототип контроллера таймера._ Обратите внимание, что у модуля нет сигнала `interrupt_return_i`. Модуль будет генерировать прерывания ровно на 1 такт. Если процессор в этот момент не будет готов обработать прерывания (обрабатывая в этот момент какой-либо другой перехват) — запрос будет сразу же пропущен и таймер начнет отсчитывать следующий. @@ -106,13 +106,13 @@ logic [63:0] system_counter_at_start; - `OFF` — отключен (не генерирует прерывания) - `NTIMES` — включен до тех пор, пока не сгенерирует N прерываний (значение N хранится в регистре `repeat_counter` и обновляется после каждого сгенерированного прерывания). После генерации N прерываний, переходит в режим `OFF`. - `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`. Уменьшается в момент генерации прерывания в этом режиме в случае, если еще не равен нулю. - `system_counter_at_start` — неархитектурный регистр, хранящий значение системного счётчика на момент начала отсчета таймера. Обновляется при генерации прерывания (если это не последнее прерывание в режиме `NTIMES`) и при запросе на запись в регистр `mode` значения не `OFF`. Выходной сигнал interrupt_request_o должен быть равен единице, если текущий режим работы не `OFF`, а сумма `system_counter_at_start` и `delay` равна `system_counter`. -Для подключения данного таймера к системной шине, мы воспользуемся первым свободным базовым адресом, оставшимся после ЛР№13: `0x08`. Таким образом, для обращения к системному счётчику, процессор будет использовать адрес `0x08000000` для обращения к регистру `delay` `0x08000008` и т.п. +Для подключения данного таймера к системной шине, мы воспользуемся первым свободным базовым адресом, оставшимся после ЛР № 13: `0x08`. Таким образом, для обращения к системному счётчику, процессор будет использовать адрес `0x08000000` для обращения к регистру `delay` `0x08000008` и т.п. ### Настройка Coremark @@ -144,7 +144,7 @@ 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): @@ -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` в адресном пространстве этого контроллера. #### 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 одним стоповым битом и контролем бита четности. В этом случае, мы должны добавить в начало функции следующий код: ```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/`. В случае, если это не так, измените первую строчку данного файла в соответствии с расположением кросс-компилятора. @@ -300,7 +300,7 @@ _Листинг 6. Лог вывода результатов coremark. Знач 3. Интегрируйте модуль `timer_sb_ctrl` в процессорную систему. 1. Ко входу `rst_i` модуля подключите сигнал `core_reset_o` программатора. Таким образом, системный счётчик начнет работать только когда память системы будет проинициализирована. 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), либо скачать его в виде архива. 6. Добавьте реализацию платформозависимых функций программы coremark. Для этого в папке `barebones` необходимо: 1. в файле `core_portme.c`: @@ -318,7 +318,7 @@ _Листинг 6. Лог вывода результатов coremark. Знач 2. В случае, если инициализация будет осуществляться посредством `$readmemh`, не забудьте удалить первую строчку со стартовым адресом из файла, инициализирующего память данных. 3. В случае, если инициализация будет осуществляться с помощью программатора, используйте вспомогательные вызовы `program_region` из пакета `bluster_pkg`, как это было сделано в `lab_15_tb_system`. 4. В исходном виде тестбенч описан под инициализацию памяти посредством `$readmemh`. -11. Выполните моделирование системы с помощью модуля [lab_16.tb_coremark](lab_16.tb_coremark). +11. Выполните моделирование системы с помощью модуля [lab_16.tb_coremark.sv](lab_16.tb_coremark.sv). 1. Результаты теста будут выведены приблизительно на `355ms` времени моделирования. ## Оценка производительности