diff --git a/Labs/13. Peripheral units/README.md b/Labs/13. Peripheral units/README.md index fba20f4..a1e8f05 100644 --- a/Labs/13. Peripheral units/README.md +++ b/Labs/13. Peripheral units/README.md @@ -1,6 +1,6 @@ # Лабораторная работа 13 "Периферийные устройства" -На прошлой лабораторной работе вы реализовали свой собственный RISC-V процессор. Однако пока что он находится "в вакууме" и никак не связан с внешним миром. Для исправления этого недостатка вами будет реализована системная шина, через которую к процессору смогут подключаться различные периферийные устройства. +В [ЛР№11](../11.%20Interrupt%20integration/) вы закончили реализовывать свой собственный RISC-V процессор. Однако пока что он находится "в вакууме" и никак не связан с внешним миром. Для исправления этого недостатка вами будет реализована системная шина, через которую к процессору смогут подключаться различные периферийные устройства. ## Цель @@ -12,8 +12,8 @@ Для успешного выполнения лабораторной работы, вам необходимо: -* ознакомиться с [примером описания модуля-контроллера](../../Basic%20Verilog%20structures/Controllers.md); -* ознакомиться с [описанием](#описание-контроллеров-периферийных-устройств) контроллеров периферийных устройств. +- ознакомиться с [примером описания модуля-контроллера](../../Basic%20Verilog%20structures/Controllers.md); +- ознакомиться с [описанием](#описание-контроллеров-периферийных-устройств) контроллеров периферийных устройств. ## Ход работы @@ -62,10 +62,10 @@ _Рисунок 1. Итоговая структура процессорной Реализация унитарного кодирования предельно проста: -* Нулевой сигнал этой шины будет равен единице только если `data_addr_o[31:24] = 8'd0`. -* Первый бит этой шины будет равен единице только если `data_addr_o[31:24] = 8'd1`. -* ... -* Двести пятьдесят пятый бит шины будет равен единице только если `data_addr_o[31:24] = 8'd255`. +- Нулевой сигнал этой шины будет равен единице только если `data_addr_o[31:24] = 8'd0`. +- Первый бит этой шины будет равен единице только если `data_addr_o[31:24] = 8'd1`. +- ... +- Двести пятьдесят пятый бит шины будет равен единице только если `data_addr_o[31:24] = 8'd255`. Для реализации такого кодирования достаточно выполнить сдвиг влево константы `255'd1` на значение `data_addr_o[31:24]`. @@ -107,7 +107,7 @@ endmodule Эти порты нужно подключить к одноименным портам ваших контроллеров периферии (**речь идет только о реализуемых вами контроллерах, остальные порты должны остаться неподключенными**). Иными словами, в описании модуля должны быть все указанные входы и выходы. Но использовать вам нужно только порты, связанные с теми периферийными устройствами, реализацию которых вам необходимо подключить к процессорной системе в рамках индивидуального задания. -Обратите внимание на то, что изменился сигнал сброса (`resetn_i`). Буква `n` на конце означает, что сброс работает по уровню `0` (когда сигнал равен нулю — это сброс, когда единице — не сброс). +Обратите внимание на то, что изменился сигнал сброса (`resetn_i`). Буква `n` на конце означает, что сброс работает по уровню `0` (в таком случае говорят, что **активный уровень** данного сигнала `0`: когда сигнал равен нулю — это сброс, когда единице — не сброс). Помимо прочего, необходимо подключить к вашему модулю `блок делителя частоты`. Поскольку в данном курсе лабораторных работ вы выполняли реализацию однотактного процессора, инструкция должна пройти через все ваши блоки за один такт. Из-за этого критический путь схемы не позволит использовать тактовый сигнал частотой в `100 МГц`, от которого работает отладочный стенд. Поэтому, необходимо создать отдельный сигнал с пониженной тактовой частотой, от которого будет работать ваша схема. @@ -121,13 +121,13 @@ logic sysclk, rst; sys_clk_rst_gen divider(.ex_clk_i(clk_i),.ex_areset_n_i(resetn_i),.div_i(5),.sys_clk_o(sysclk), .sys_reset_o(rst)); ``` -3. После вставки данных строк в начало описания модуля `riscv_unit` вы получите тактовый сигнал `sysclk` с частотой в 10 МГц и сигнал сброса `rst` с активным уровнем `1` (как и в предыдущих лабораторных). Все ваши внутренние модули (`riscv_core`, `data_mem` и `контроллеры периферии`) должны работать от тактового сигнала `sysclk`. На модули, имеющие входной сигнал сброса (`rst_i`) необходимо подать ваш сигнал `rst`. +3. После вставки данных строк в начало описания модуля `riscv_unit` вы получите тактовый сигнал `sysclk` с частотой в 10 МГц и сигнал сброса `rst` с активным уровнем `1` (как и в предыдущих лабораторных). Все ваши внутренние модули (`riscv_core`, `data_mem` и контроллеры периферии) должны работать от тактового сигнала `sysclk`. На модули, имеющие входной сигнал сброса (`rst_i`) необходимо подать ваш сигнал `rst`. --- ## Задание -В рамках данной лабораторной работы необходимо реализовать модули-контроллеры двух периферийных устройств, реализующих управление в соответствии с приведенной на _рис. 2_ картой памяти и встроить их в процессорную систему, используя [_рис. 1_](../../.pic/Labs/lab_13_periph/fig_01.drawio.svg). На карте приведено шесть периферийных устройств, вам необходимо взять только два из них. Какие именно — сообщит преподаватель. +В рамках данной лабораторной работы необходимо реализовать модули-контроллеры двух периферийных устройств, реализующих управление в соответствии с приведенной на _рис. 2_ картой памяти и встроить их в процессорную систему, используя [_рис. 1_](../../.pic/Labs/lab_13_periph/fig_01.drawio.svg). На карте приведено семь периферийных устройств, вам необходимо взять только два из них. Какие именно — сообщит преподаватель. ![Карта памяти](../../.pic/Labs/lab_13_periph/fig_02.png) @@ -136,8 +136,8 @@ _Рисунок 2. Карта памяти периферийных устрой Работа с картой осуществляется следующим образом. Под названием каждого периферийного устройства указана старшая часть адреса (чему должны быть равны старшие 8 бит адреса, чтобы было сформировано обращение к данному периферийному устройству). Например, для переключателей это значение равно `0x01`, для светодиодов `0x02` и т.п. В самом левом столбце указаны используемые/неиспользуемые адреса в адресном пространстве данного периферийного устройства. Например для переключателей есть только один используемый адрес: `0x000000`. Его функциональное назначение и разрешения на доступ указаны в столбце соответствующего периферийного устройства. Возвращаясь к адресу `0x000000`, для переключателей мы видим следующее: -* **(R)** означает что разрешен доступ только на чтение (операция записи по этому адресу должна игнорироваться вашим контроллером). -* **"Выставленное на переключателях значение"** означает ровно то, что и означает. Если процессор выполняет операцию чтения по адресу `0x01000000` (`0x01` [старшая часть адреса переключателей] + `0x000000` [младшая часть адреса для получения выставленного на переключателях значения]), то контроллер должен выставить на выходной сигнал `RD` значение на переключателях (о том как получить это значение будет рассказано чуть позже). +- **(R)** означает что разрешен доступ только на чтение (операция записи по этому адресу должна игнорироваться вашим контроллером). +- **"Выставленное на переключателях значение"** означает ровно то, что и означает. Если процессор выполняет операцию чтения по адресу `0x01000000` (`0x01` [старшая часть адреса переключателей] + `0x000000` [младшая часть адреса для получения выставленного на переключателях значения]), то контроллер должен выставить на выходной сигнал `RD` значение на переключателях (о том как получить это значение будет рассказано чуть позже). Рассмотрим еще один пример. При обращении по адресу `0x02000024` (`0x02` (старшая часть адреса контроллера светодиодов) + `0x000024` (младшая часть адреса для доступа на запись к регистру сброса) ) должна произойти запись в регистр сброса, который должен сбросить значения в регистре управления зажигаемых светодиодов и регистре управления режимом "моргания" светодиодов (подробнее о том как должны работать эти регистры будет ниже). @@ -154,24 +154,26 @@ _Рисунок 2. Карта памяти периферийных устрой 1. Внимательно ознакомьтесь с [примером описания модуля контроллера](../../Basic%20Verilog%20structures/Controllers.md). 2. Внимательно ознакомьтесь со спецификацией контроллеров периферии своего варианта. В случае возникновения вопросов, проконсультируйтесь с преподавателем. -3. Реализуйте модули контроллеров периферии. Имена модулей и их порты будут указаны в [описании контроллеров](#описание-контроллеров-периферийных-устройств). Пример разработки контроллера приведен [здесь](../../Basic%20Verilog%20structures/Controllers.md). +3. Реализуйте модули контроллеров периферии. Имена модулей и их порты будут указаны в [описании контроллеров](#описание-контроллеров-периферийных-устройств). Пример разработки контроллера приведен в [примере описания модуля контроллера](../../Basic%20Verilog%20structures/Controllers.md). 1. Готовые модули периферии, управление которыми должны осуществлять модули-контроллеры хранятся в папке `peripheral modules`. 4. Обновите модуль `riscv_unit` в соответствии с разделом ["Дополнительные правки модуля riscv_unit"](#дополнительные-правки-модуля-riscv_unit). 1. Подключите в проект файл `sys_clk_rst_gen.sv`. - 2. Добавьте в модуль `riscv_unit` входы и выходы периферии. **Необходимо добавить порты даже тех периферийных устройств, которые вы не будете реализовывать**. + 2. Добавьте в модуль `riscv_unit` входы и выходы периферии, а так же замените вход `rst_i` входом `resetn_i`. **Необходимо добавить порты даже тех периферийных устройств, которые вы не будете реализовывать**. 3. Создайте в начале описания модуля `riscv_unit` экземпляр модуля `sys_clk_rst_gen`, скопировав приведенный фрагмент кода. 4. Замените подключение тактового сигнала исходных подмодулей `riscv_unit` на появившийся сигнал `sysclk`. Убедитесь, что на модули, имеющие сигнал сброса, приходит сигнал `rst`. 5. Интегрируйте модули контроллеров периферии в процессорную систему по приведенной схеме руководствуясь старшими адресами контроллеров, представленными на карте памяти ([_рис. 2_](../../.pic/Labs/lab_13_periph/fig_02.png)). Это означает, что если вы реализуете контроллер светодиодов, на его вход `req_i` должна подаваться единица в случае, если `mem_req_o == 1` и старшие 8 бит адреса равны `0x02`. 1. При интеграции вы должны подключить только модули-контроллеры вашего варианта. Контроллеры периферии других вариантов подключать не надо. - 2. При этом во время интеграции, вы должны использовать старшую часть адреса, представленную в карте памяти для формирования сигнала `req_i` для ваших модулей-контроллеров. + 2. Во время интеграции, вы должны использовать старшую часть адреса, представленную в карте памяти для формирования сигнала `req_i` для ваших модулей-контроллеров. 6. Проверьте работу процессорной системы с помощью моделирования. - 1. Для каждой пары контроллеров в папке `firmware/mem_files` представлены файлы, инициализирующие память инструкций. Обратите внимание, что для пары "PS2-VGA" также необходим файл, инициализирующий память данных (в модуле `ext_mem` необходимо прописать блок `$readmemh`). - 2. Исходный код программ с адресами и результирующими инструкциями находится в папке `firmware/software`. - 3. При моделировании светодиодов лучше уменьшить значение, до которого считает счетчик в режиме "моргания" в 1000 раз, чтобы сократить время моделирования до очередного переключения светодиодов. Перед генерацией битстрима это значение будет необходимо восстановить. - 4. Для проверки тестбенч имитирует генерацию данных периферийных устройств ввода. При реализации контроллера клавиатуры или uart_rx рекомендуется ознакомиться с тем, какие именно данные тестбенч подает на вход. - 5. Для того, чтобы понять, что устройство работает должным образом, в первую очередь необходимо убедиться, что контроллер устройства ввода успешно осуществил прием данных (сгенерированные тестбенчем данные оказались в соответствующем регистре контроллера периферийного устройства) и сгенерировал запрос на прерывание. - 6. После чего, необходимо убедиться, что процессор среагировал на данное прерывание, и в процессе его обработки в контроллер устройства вывода были поданы выходные данные. - 7. Для того, чтобы лучше понимать как именно процессор будет обрабатывать прерывание, рекомендуется ознакомиться с исходным кодом исполняемой программы, расположенным в папке `firmware/software`. + 1. Для каждой пары контроллеров в папке `firmware/mem_files` представлены файлы, инициализирующие память инструкций. Обратите внимание, что для пары "PS2-VGA" также необходим файл, инициализирующий память данных (в модуле `data_mem` необходимо добавить вызов инициализирующей функции `$readmemh` в блоке `initial`). + 2. Для проверки тестбенч имитирует генерацию данных периферийных устройств ввода. Перед проверкой желательно найти в тестбенче `initial`-блок своего устройства ввода (`sw_block`, `ps2_block`, `uart_block`) — по этому блоку будет понятно, какие данные будет передавать устройство ввода. Именно эти данные в итоге должны оказаться на шине `mem_rd_i`. + 3. Для того, чтобы понять, что устройство работает должным образом, в первую очередь необходимо убедиться, что контроллер устройства ввода успешно осуществил прием данных (сгенерированные тестбенчем данные оказались в соответствующем регистре контроллера периферийного устройства) и выполнил запрос на прерывание. + 4. После чего, необходимо убедиться, что процессор среагировал на данное прерывание, и в процессе его обработки в контроллер устройства вывода были поданы выходные данные. + 5. Для того, чтобы лучше понимать как именно процессор будет обрабатывать прерывание, рекомендуется ознакомиться с исходным кодом исполняемой программы, расположенным в папке `firmware/software`. + 1. Общая логика программ для всех периферий сводится к ожиданию в бесконечном цикле прерывания от устройства ввода, после чего в процессе обработки прерывания процессор загружает данные от устройства ввода и (возможно преобразовав их) выдает их на устройство вывода. + 2. В случае правильной работы программы на временной диаграмме это будет отображено следующим образом: сразу после поступления прерывания от устройства ввода, на системной шине начинается операция чтения из устройства ввода (это легко определить по старшей части адреса, к которому обращается процессор), после чего выполняются операции записи в устройство вывода (аналогично, обращение к устройству вывода можно определить по адресу, к которому обращается процессор). + 6. При моделировании светодиодов лучше уменьшить значение, до которого считает счетчик в режиме "моргания" в 1000 раз, чтобы сократить время моделирования до очередного переключения светодиодов. Перед генерацией битстрима это значение будет необходимо восстановить, иначе моргание станет слишком быстрым и его нельзя будет воспринять невооруженным взглядом. + 7. Переходить к следующему пункту можно только после того, как вы полностью убедились в работоспособности модуля на этапе моделирования (увидели корректные значения на выходных сигналах периферии, либо (если по сигналам периферии сложно судить о работоспособности), значениям в контрольных/статусных регистрах модуля-контроллера этой периферии). Генерация битстрима будет занимать у вас долгое время, а итогом вы получите результат: заработало / не заработало, без какой-либо дополнительной информации, поэтому без прочного фундамента на моделировании далеко уехать у вас не выйдет. 8. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе. @@ -195,13 +197,13 @@ _Рисунок 2. Карта памяти периферийных устрой 3. На входе `write_enable_i` выставлено значение `0`. 4. На входе `addr_i` выставлено значение `0xАДРЕС` -Обратите внимание на то, что **запрос на чтение** должен обрабатываться **синхронно** (выходные данные должны выдаваться по положительному фронту `clk_i`). +Обратите внимание на то, что **запрос на чтение** должен обрабатываться **синхронно** (выходные данные должны выдаваться по положительному фронту `clk_i`) так же как был реализован порт на чтение памяти данных в [ЛР№6](../06.%20Main%20memory/). -При описании поддерживаемых режимов доступа по данному адресу используется следующее обозначение: +При описании поддерживаемых режимов доступа по данному адресу используются следующее обозначения: -* R — доступ **только на чтение**; -* W — доступ **только на запись**; -* RW — доступ на **чтение и запись**. +- R — доступ **только на чтение**; +- W — доступ **только на запись**; +- RW — доступ на **чтение и запись**. В случае отсутствия **запроса на чтение**, на выходе `read_data_o` не должно меняться значение (тоже самое было сделано в процессе разработки памяти данных). @@ -288,15 +290,15 @@ logic led_mode; endmodule ``` -Данный модуль должен выводить на выходной сигнал `led_o` данные с регистра `led_val`. Запись и чтение регистра `led_val` осуществляется по адресу `0x00`. Запись любого значения, превышающего `2¹⁶-1` должна игнорироваться. +Данный модуль должен подавать на выходной сигнал `led_o` данные с регистра `led_val`. Запись и чтение регистра `led_val` осуществляется по адресу `0x00`. -Регистр `led_mode` отвечает за режим вывода данных на светодиоды. Когда этот регистр равен единице, светодиоды должны "моргать" выводимым значением. Под морганием подразумевается вывод значения из регистра `led_val` на выход `led_o` на одну секунду (загорится часть светодиодов, соответствующие которым биты шины `led_o` равны единице), после чего на одну секунду выход `led_o` необходимо подать нули. Запись и чтение регистра `led_mode` осуществляется по адресу `0x04`. Запись любого значения, отличного от `0` и `1` в регистр `led_mode` должна игнорироваться. +Регистр `led_mode` отвечает за режим вывода данных на светодиоды. Когда этот регистр равен единице, светодиоды должны "моргать" выводимым значением. Под морганием подразумевается вывод значения из регистра `led_val` на выход `led_o` на одну секунду (загорится часть светодиодов, соответствующие которым биты шины `led_o` равны единице), после чего на одну секунду выход `led_o` необходимо подать нули. Запись и чтение регистра `led_mode` осуществляется по адресу `0x04`. Отсчет времени можно реализовать простейшим счетчиком, каждый такт увеличивающимся на 1 и сбрасывающимся по достижении определенного значения, чтобы продолжить считать с нуля. Зная тактовую частоту, нетрудно определить до скольки должен считать счетчик. При тактовой частоте в 10 МГц происходит 10 миллионов тактов в секунду. Это означает, что при такой тактовой частоте через секунду счетчик будет равен `10⁷-1` (счет идет с нуля). Тем не менее удобней будет считать не до `10⁷-1` (что было бы достаточно очевидным и тоже правильным решением), а до `2*10⁷-1`. В этом случае старший бит счетчика каждую секунду будет инвертировать свое значение, что может быть использовано при реализации логики "моргания". Важно отметить, что счетчик должен работать только при `led_mode == 1`, в противном случае счетчик должен быть равен нулю. -Обратите внимание на то, что адрес `0x24` является адресом сброса. В случае **запроса на запись** по этому адресу значения `1`. вы должны сбросить регистры `led_val`, `led_mode` и все вспомогательные регистры, которые вы создали. Для реализации сброса вы можете как создать отдельный регистр `led_rst`, в который будет происходить запись, а сам сброс будет происходить по появлению единицы в этом регистре (в этом случае необходимо не забыть сбрасывать и этот регистр), так и создать обычный провод, формирующий единицу в случае выполнения всех указанных условий (условий **запроса на запись**, адреса сброса и значения записываемых данных равному единице). +Обратите внимание на то, что адрес `0x24` является адресом сброса. В случае **запроса на запись** по этому адресу значения `1`. вы должны сбросить регистры `led_val`, `led_mode` и все вспомогательные регистры, которые вы создали. Для реализации сброса вы можете как создать отдельный регистр `led_rst`, в который будет происходить запись, а сам сброс будет происходить по появлению единицы в этом регистре (в этом случае необходимо не забыть сбрасывать и этот регистр тоже), так и создать обычный провод, формирующий единицу в случае выполнения всех указанных условий (условий **запроса на запись**, адреса сброса и значения записываемых данных равному единице). Адресное пространство контроллера: @@ -449,7 +451,7 @@ endmodule Доступ на чтение/запись регистра `bitmask` осуществляется по адресу `0x20`. -При **запросе на запись** единицы по адресу `0x24` необходимо выполнить сброс всех регистров. При этом регистр `bitmask` должен сброситься в значение `0xFF`. +При **запросе на запись** единицы по адресу `0x24` необходимо выполнить сброс всех регистров. При этом регистр `bitmask` должен сброситься в значение `0xFF` (т.е. после сброса все семисегментные индикаторы должны загореться с цифрой `0`). Адресное пространство контроллера: @@ -472,9 +474,9 @@ endmodule Для того, чтобы передача данных была успешно осуществлена, приемник и передатчик на обоих концах одного провода должны договориться о параметрах передачи: -* её скорости (бодрейт); -* контроля целостности данных (использовать или нет [бит четности](https://en.wikipedia.org/wiki/Parity_bit)); -* длины стопового бита. +- её скорости (бодрейт); +- контроля целостности данных (использовать или нет [бит четности](https://en.wikipedia.org/wiki/Parity_bit)); +- длины стопового бита. Вам будут предоставлены модули, осуществляющие прием и передачу данных по этому интерфейсу, от вас лишь требуется написать модули, осуществляющие управление предоставленными модулями. @@ -643,7 +645,7 @@ _Рисунок 3. Пример игры с использованием сим _Рисунок 4. Карта памяти vga-модуля._ -Для того, чтобы вывести символ на экран, необходимо использовать адрес этого символа на сетке `80x30` (диапазон адресов `char_map`). К примеру, мы хотим вывести символ в верхнем левом углу. Это нулевой символ в диапазоне адресов `char_map`. Поскольку данный диапазон начинается с адреса `0x0000_0000`, запись по этому адресу приведет к отображению символа, соответствующего [ASCII-коду](https://www.asciitable.com/), пришедшему на `write_data_i`. +Для того, чтобы вывести символ на экран, необходимо использовать адрес этого символа на сетке `80x30` (диапазон адресов `char_map`). К примеру, мы хотим вывести символ в верхнем левом углу (т.е. нулевой символ нулевой строки). Это нулевой символ в диапазоне адресов `char_map`. Поскольку данный диапазон начинается с адреса `0x0000_0000`, запись по этому адресу приведет к отображению символа, соответствующего [ASCII-коду](https://www.asciitable.com/), пришедшему на `write_data_i`. Если мы хотим вывести нулевой (левый) символ в первой строке (счет ведется с нуля), то необходимо произвести запись по адресу `1*80 + 0 = 80 = 0x0000_0050`. @@ -651,9 +653,9 @@ _Рисунок 4. Карта памяти vga-модуля._ Установка цветовой схемы осуществляется по тем же самым адресам, к которым прибавлено значение `0x0000_1000`: -* верхний левый символ — `0x0000_1000` -* нулевой символ первой строки — `0x0000_1050` -* нижний правый символ — `0x0000_195F` +- верхний левый символ — `0x0000_1000` +- нулевой символ первой строки — `0x0000_1050` +- нижний правый символ — `0x0000_195F` Цветовая схема каждой позиции состоит из двух цветов: цвета фона и цвета символа. Оба эти цвета выбираются из палитры 8 цветов, каждый из которых содержит два оттенка: цвет на полной яркости и цвет на уменьшенной яркости (см. _рис. 5_). Один из цветов — черный, оба его оттенка представляют собой один и тот же цвет. На _рис. 5_ приведены коды цветов их rgb-значения: @@ -663,9 +665,9 @@ _Рисунок 5. Цветовая палитра vga-модуля._ Код цвета формируется следующим образом: старший бит определяет яркость оттенка цвета. Оставшиеся 3 бита кодируют используемый канал: -* 0 бит кодирует использование синего канала; -* 1 бит кодирует использование зеленого канала; -* 2 бит кодирует использование красного канала. +- 0 бит кодирует использование синего канала; +- 1 бит кодирует использование зеленого канала; +- 2 бит кодирует использование красного канала. Таким образом, для установки цветовой схемы, необходимо выбрать два цвета из палитры, склеить их (в старших разрядах идет цвет символа, в младших — цвет фона) и записать получившееся 8-битное значение по адресу выбранной позиции в диапазоне адресов цветовой схемы (color_map). @@ -685,13 +687,15 @@ _Рисунок 6. Отрисовка символа `F` в разрешении Для хранения шрифтов в модуле отведен диапазон адресов `0x00002000-0x00002FFF`. В отличие от предыдущих диапазонов адресов, где каждый адрес был закреплен за соответствующей позицией символа в сетке `80x30`, адреса данного диапазона распределены следующим образом: -* 0-ой байт — нулевая (верхняя) строчка символа с кодом 0; -* 1-ый байт — первая строчка символа с кодом 0; -* ... -* 15-ый байт — пятнадцатая (нижняя) строчка символа с кодом 0; -* 16-ый байт — нулевая (верхняя) строчка символа с кодом 1; -* ... -* 4095-ый байт — пятнадцатая (нижняя) строчка символа с кодом 255. +- 0-ой байт — нулевая (верхняя) строчка символа с кодом 0; +- 1-ый байт — первая строчка символа с кодом 0; +- ... +- 15-ый байт — пятнадцатая (нижняя) строчка символа с кодом 0; +- 16-ый байт — нулевая (верхняя) строчка символа с кодом 1; +- ... +- 4095-ый байт — пятнадцатая (нижняя) строчка символа с кодом 255. + +Для простоты работы с модулем вам будут даны файлы, которыми можно проинициализировать память шрифтов и цветов. В этом случае вам будет достаточно только записывать выводимые символы по нужным адресам. Прототип vga-модуля следующий: @@ -739,15 +743,14 @@ module vgachargen ( Файлы модуля: -* peripheral modules/vhachargen.sv -* peripheral modules/vhachargen_pkg.sv -* firmware/mem_files/lab_13_ps2_vga_instr.mem — этим файлом необходимо проинициализировать память инструкций -* firmware/mem_files/lab_13_ps2ascii_data.mem — этим файлом необходимо проинициализировать память данных -* firmware/mem_files/lab_13_vga_ch_map.mem -* firmware/mem_files/lab_13_vga_ch_t.mem -* firmware/mem_files/lab_13_vga_col_map.mem +- peripheral modules/vhachargen.sv +- peripheral modules/vhachargen_pkg.sv +- firmware/mem_files/lab_13_ps2_vga_instr.mem — этим файлом необходимо проинициализировать память инструкций +- firmware/mem_files/lab_13_ps2ascii_data.mem — этим файлом необходимо проинициализировать память данных +- firmware/mem_files/lab_13_vga_ch_t.mem +- firmware/mem_files/lab_13_vga_col_map.mem -Вам необходимо добавить в проект все эти файлы. +Вам необходимо добавить в проект все эти файлы. Последние два файла отвечают за инициализацию памятей шрифтов и цветов. Инициализация будет выполнена автоматически. Главное, чтобы файлы были добавлены в проект. Для управления данным модулем, необходимо написать модуль-контроллер со следующим прототипом: @@ -773,14 +776,14 @@ module vga_sb_ctrl ( Реализация данного модуля исключительно простая. В первую очередь необходимо подключить одноименные сигналы напрямую: -* `clk_i`, -* `rst_i`, -* `clk100m_i`, -* `vga_r_o`, -* `vga_g_o`, -* `vga_b_o`, -* `vga_hs_o`, -* `vga_vs_o` +- `clk_i`, +- `rst_i`, +- `clk100m_i`, +- `vga_r_o`, +- `vga_g_o`, +- `vga_b_o`, +- `vga_hs_o`, +- `vga_vs_o` Кроме того, необходимо: