diff --git a/Labs/14. Programming/README.md b/Labs/14. Programming/README.md index cf0042a..79e7668 100644 --- a/Labs/14. Programming/README.md +++ b/Labs/14. Programming/README.md @@ -1,6 +1,6 @@ # Лабораторная работа 14 "Высокоуровневое программирование" -Благодаря абстрагированию можно создавать действительно сложные системы — из вентелей можно собрать модули, из модулей микроархитектуру и так далее. В этом контексте архитектура выступает как фундамент, на котором строится программный стек абстракций. На основе архитектур строятся ассемблеры, на основе которых "строятся" языки высокого уровня, на основе которых создаются фреймворки и метафреймворки, что обеспечивает более высокий уровень и удобство при разработке новых программ. Давайте немного глубже погрузимся в этот стек. +Благодаря абстрагированию можно создавать действительно сложные системы — из вентилей можно собрать модули, из модулей микроархитектуру и так далее. В этом контексте архитектура выступает как фундамент, на котором строится программный стек абстракций. На основе архитектур строятся ассемблеры, на основе которых "строятся" языки высокого уровня, на основе которых создаются фреймворки и метафреймворки, что обеспечивает более высокий уровень и удобство при разработке новых программ. Давайте немного глубже погрузимся в этот стек. ## Цель @@ -299,6 +299,8 @@ SECTIONS _Листинг 1. Пример скрипта компоновщика с комментариями._ +Обратите внимание на указанные размеры памяти инструкций и данных. Они отличаются от размеров, которые использовались ранее в пакете `memory_pkg`. Дело в том, что пока система и исполняемые ей программы были простыми, в большом объеме памяти не было нужды и меньший размер значительно сокращал время синтеза системы. Однако в данный момент, чтобы обеспечить программе достаточно места под инструкции, а так же программный стек и стек прерываний, необходимо увеличить объемы памяти инструкций и памяти данных. Для этого необходимо обновить значения параметров `INSTR_MEM_SIZE_BYTES` и `DATA_MEM_SIZE_BYTES` на 32'd1024 и 32'd2048 соответственно. В зависимости от сложности вашего проекта, в будущем вам может снова потребоваться изменять размер памяти в вашей системе. Помните, все изменения в memory_pkg должны отражаться и в скрипте компоновщика для вашей системы. + ### Файл первичных команд при загрузке (startup.S) В стартап-файле хранятся инструкции, которые обязательно необходимо выполнить перед началом исполнения любой программы. Это инициализация регистров указателей на стек и глобальную область данных, контрольных регистров системы прерывания и т.п. @@ -723,21 +725,24 @@ _Листинг 4. Пример кода на C++, взаимодействую ### Порядок выполнения задания -1. Внимательно изучить разделы теории и практики. -2. Разобрать принцип взаимодействия с контрольными и статусными регистрами периферийного устройства на примере _Листинга 4_. -3. Написать программу для своего индивидуального задания и набора периферийных устройств на языке C или C++. В случае написания кода на C++ помните о необходимости добавления `extern "C"` перед определением функции `int_handler`. +1. Внимательно изучите разделы теории и практики. +2. Разберите принцип взаимодействия с контрольными и статусными регистрами периферийного устройства на примере _Листинга 4_. +3. Обновите значения параметров `INSTR_MEM_SIZE_BYTES` и `DATA_MEM_SIZE_BYTES` в пакете `memory_pkg` на 32'd1024 и 32'd2048 соответственно. Поскольку пакеты не являются модулями, вы не увидите их во вкладке `Hierarchy` окна исходников, вместо этого вы сможете найти их во вкладках `Libraries` и `Compile order`. +4. Напишите программу для своего индивидуального задания и набора периферийных устройств на языке C или C++. В случае написания кода на C++ помните о необходимости добавления `extern "C"` перед определением функции `int_handler`. 1. В описываемой программе обязательно должны присутствовать функции `main` и `int_handler`, т.к. в стартап-файле описаны вызовы этих функций. При необходимости, вы можете описать необходимые вам вспомогательные функции — ограничений на то что должно быть ровне две этих функции нет. 2. Функция `main` может быть пустой — по ее завершению в стартап-файле предусмотрен бесконечный цикл, из которого процессор сможет выходить только по прерыванию. 3. В функции `int_handler` вам необходимо считать поступившие от устройства ввода входные данные. 4. Вам необходимо самостоятельно решить, как вы хотите построить ход работы вашей программы: будет ли ваше индивидуальное задание вычисляться всего лишь 1 раз в функции `main`, данные в которую поступят от функции `int_handler` через глобальные переменные, или же оно будет постоянно пересчитываться при каждом вызове `int_handler`. 5. Доступ к регистрам контроля и статуса необходимо осуществлять посредством указателей на структуры, объявленные в файле [platform.h](./platform.h). В случае VGA-контроллера, доступ к областям памяти осуществляется через экземпляр структуры (а не указатель на нее), содержащий имена массивов `char_map`, `color_map` и `tiff_map`. -4. [Скомпилировать](#практика) программу и [стартап-файл](startup.S) в объектные файлы. -5. Скомпоновать объектные файлы исполняемый файл, передав компоновщику соответствующий [скрипт](linker_script.ld). -6. Экспортировать из объектного файла секции `.text` и `.data` в текстовые файлы `init_instr.mem`, `init_data.mem`. Если вы не создавали инициализированных статических массивов или глобальных переменных, то файл `init_data.mem` может быть оказаться пустым. +5. [Скомпилируйте](#практика) программу и [стартап-файл](startup.S) в объектные файлы. +6. Скомпонуйте объектные файлы исполняемый файл, передав компоновщику соответствующий [скрипт](linker_script.ld). +7. Экспортируйте из объектного файла секции `.text` и `.data` в текстовые файлы `init_instr.mem`, `init_data.mem`. Если вы не создавали инициализированных статических массивов или глобальных переменных, то файл `init_data.mem` может быть оказаться пустым. 1. Если файл `init_data.mem` не пустой, необходимо проинициализировать память в модуле `ext_mem` c помощью системной функции `$readmemh` как это было сделано для памяти инструкций. 2. Перед этим из файла `init_data.mem` необходимо удалить первую строку (вида `@20000000`), указывающую начальный адрес инициализации. -7. Добавить получившиеся текстовые файлы в проект Vivado. -8. Запустить моделирование исполнения программы вашим процессором. Для отладки во время моделирования будет удобно использовать дизасемблерный файл, ориентируясь на сигналы адреса и данных шины инструкций. -9. Проверить корректное исполнение программы процессором в ПЛИС. +8. Добавьте получившиеся текстовые файлы в проект Vivado. +9. Запустите моделирование исполнения программы вашим процессором с помощью тестбенча из ЛР№13. + 1. В `peripheral_pkg` находятся вспомогательные вызовы, позволяющие сымитировать ввод с клавиатуры или uart (для переключателей никаких вспомогательных вызовов не требуется). Пример имитации ввода вы можете посмотреть в тестбенче. Обновите код тестбенча таким образом, чтобы в вашу систему были поданы необходимые для работы вашей программы данные. + 2. Для отладки во время моделирования будет удобно использовать дизасемблерный файл, ориентируясь на сигналы адреса и данных шины инструкций. +10. Проверьте корректное исполнение программы процессором в ПЛИС. ---