mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 17:20:10 +00:00
BREAKING CHANGE! Сдвиг нумерации в лабах
Лабу по дейзи-цепочке необходимо вставить сразу после лабы по интеграции контроллера прерываний, поэтому приходится увеличить нумерацию оставшихся лаб.
This commit is contained in:
805
Labs/13. Peripheral units/README.md
Normal file
805
Labs/13. Peripheral units/README.md
Normal file
@@ -0,0 +1,805 @@
|
||||
# Лабораторная работа 13 "Периферийные устройства"
|
||||
|
||||
На прошлой лабораторной работе вы реализовали свой собственный RISC-V процессор. Однако пока что он находится "в вакууме" и никак не связан с внешним миром. Для исправления этого недостатка вами будет реализована системная шина, через которую к процессору смогут подключаться различные периферийные устройства.
|
||||
|
||||
## Цель
|
||||
|
||||
Интегрировать периферийные устройства в процессорную систему.
|
||||
|
||||
---
|
||||
|
||||
## Допуск к лабораторной работе
|
||||
|
||||
Для успешного выполнения лабораторной работы, вам необходимо:
|
||||
|
||||
* ознакомиться с [примером описания модуля-контроллера](../../Basic%20Verilog%20structures/Controllers.md);
|
||||
* ознакомиться с [описанием](#описание-контроллеров-периферийных-устройств) контроллеров периферийных устройств.
|
||||
|
||||
## Ход работы
|
||||
|
||||
1. Изучить теорию об адресном пространстве
|
||||
2. Получить индивидуальный вариант со своим набором периферийных устройств
|
||||
3. Интегрировать контроллеры периферийных устройств в адресное пространство вашей системы
|
||||
4. Собрать финальную схему вашей системы
|
||||
5. Проверить работу системы в ПЛИС с помощью демонстрационного ПО, загружаемого в память инструкций
|
||||
|
||||
---
|
||||
|
||||
## Теория
|
||||
|
||||
Помимо процессора и памяти, третьим ключевым элементом вычислительной системы является система ввода/вывода, обеспечивающая обмен информации между ядром вычислительной машины и периферийными устройствами[1, стр. 364].
|
||||
|
||||
Любое периферийное устройство со стороны вычислительной машины видится как набор ячеек памяти (регистров). С помощью чтения и записи этих регистров происходит обмен информации с периферийным устройством, и управление им. Например, датчик температуры может быть реализован самыми разными способами, но для процессора он в любом случае ячейка памяти, из которой он считывает число – температуру.
|
||||
|
||||
Система ввода/вывода может быть организована одним из двух способов: с **выделенным адресным пространством** устройств ввода/вывода, или с **совместным адресным пространством**. В первом случае система ввода/вывода имеет отдельную шину для подключения к процессору (и отдельные инструкции для обращения к периферии), во втором – шина для памяти и системы ввода/вывода общая (а обращение к периферии осуществляется теми же инструкциями, что и обращение к памяти).
|
||||
|
||||
### Адресное пространство
|
||||
|
||||
Архитектура RISC-V подразумевает использование совместного адресного пространства — это значит, что в лабораторной работе будет использована единая шина для подключения памяти и регистров управления периферийными устройствами. При обращении по одному диапазону адресов процессор будет попадать в память, при обращении по другим – взаимодействовать с регистрами управления/статуса периферийного устройства. Например, можно разделить 32-битное адресное пространство на 256 частей, отдав старшие 8 бит адреса под указание конкретного периферийного устройства. Тогда каждое из периферийных устройств получит 24-битное адресное пространство (16 MiB). Допустим, мы распределили эти части адресного пространства в следующем порядке (от младшего диапазона адресов к старшему):
|
||||
|
||||
0. Память данных
|
||||
1. Переключатели
|
||||
2. Светодиоды
|
||||
3. Клавиатура PS/2
|
||||
4. Семисегментные индикаторы
|
||||
5. UART-приемник
|
||||
6. UART-передатчик
|
||||
7. Видеоадаптер
|
||||
|
||||
В таком случае, если мы захотим обратиться к первому (счет идет с нуля) байту семисегментных индикаторов, мы должны будем использовать адрес `0x04000001`. Старшие 8 бит (`0x04`) определяют выбранное периферийное устройство, оставшиеся 24 бита определяют конкретный адрес в адресном пространстве этого устройства.
|
||||
|
||||
На рисунке ниже представлен способ подключения процессора к памяти инструкций и данных, а также 255 периферийным устройствам.
|
||||
|
||||

|
||||
|
||||
_Рисунок 1. Итоговая структура процессорной системы._
|
||||
|
||||
### Активация выбранного устройства
|
||||
|
||||
В зависимости от интерфейса используемой шины, периферийные устройства либо знают какой диапазон адресов им выделен (например, в интерфейсе I²C), либо нет (интерфейс APB). В первом случае, устройство понимает что к нему обратились непосредственно по адресу в данном обращении, во втором случае — по специальному сигналу.
|
||||
|
||||
На _рис. 1_ используется второй вариант — устройство понимает, что к нему обратились по специальному сигналу `req_i`. Данный сигнал формируется из двух частей: сигнала `req` исходящего из процессорного ядра (сигнал о том, обращение в память вообще происходит) и специального сигнала-селектора исходящего из 256-разрядной шины. Формирование значения на этой шине происходит с помощью [унитарного](https://ru.wikipedia.org/wiki/Унитарный_код) ([one-hot](https://en.wikipedia.org/wiki/One-hot)) кодирования. Процесс кодирования достаточно прост. В любой момент времени на выходной шине должен быть **ровно один** бит, равный единице. Индекс этого бита совпадает со значением старших восьми бит адреса. Поскольку для восьмибитного значения существует 256 комбинаций значений, именно такая разрядность будет на выходе кодировщика. Это означает, что в данной системе можно связать процессор с 256 устройствами (одним из которых будет память данных).
|
||||
|
||||
Реализация такого кодирования предельно проста:
|
||||
|
||||
* Нулевой сигнал этой шины будет равен единице только если `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]`.
|
||||
|
||||
### Дополнительные правки модуля riscv_unit
|
||||
|
||||
Ранее, для того чтобы ваши модули могли работать в ПЛИС, вам предоставлялся специальный модуль верхнего уровня, который выполнял всю работу по связи с периферией через входы и выходы ПЛИС. Поскольку в текущей лабораторной вы завершаете свою процессорную систему, она сама должна оказаться модулем верхнего уровня, а значит здесь вы должны и выполнить всё подключение к периферии.
|
||||
|
||||
Для этого необходимо добавить в модуль `riscv_unit` дополнительные входы и выходы, которые подключены посредством файла ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)) к входам и выходам ПЛИС.
|
||||
|
||||
```SystemVerilog
|
||||
module riscv_unit(
|
||||
input logic clk_i,
|
||||
input logic resetn_i,
|
||||
|
||||
// Входы и выходы периферии
|
||||
input logic [15:0] sw_i, // Переключатели
|
||||
|
||||
output logic [15:0] led_o, // Светодиоды
|
||||
|
||||
input logic kclk_i, // Тактирующий сигнал клавиатуры
|
||||
input logic kdata_i, // Сигнал данных клавиатуры
|
||||
|
||||
output logic [ 6:0] hex_led_o, // Вывод семисегментных индикаторов
|
||||
output logic [ 7:0] hex_sel_o, // Селектор семисегментных индикаторов
|
||||
|
||||
input logic rx_i, // Линия приема по UART
|
||||
output logic tx_o, // Линия передачи по UART
|
||||
|
||||
output logic [3:0] vga_r_o, // красный канал vga
|
||||
output logic [3:0] vga_g_o, // зеленый канал vga
|
||||
output logic [3:0] vga_b_o, // синий канал vga
|
||||
output logic vga_hs_o, // линия горизонтальной синхронизации vga
|
||||
output logic vga_vs_o // линия вертикальной синхронизации vga
|
||||
|
||||
);
|
||||
//...
|
||||
endmodule
|
||||
```
|
||||
|
||||
Эти порты нужно подключить к одноименным портам ваших контроллеров периферии (**речь идет только о реализуемых вами контроллерах, остальные порты должны остаться неподключенными**). Иными словами, в описании модуля должны быть все указанные входы и выходы. Но использовать вам нужно только порты, связанные с теми периферийными устройствами, реализацию которых вам необходимо подключить к процессорной системе в рамках индивидуального задания.
|
||||
|
||||
Обратите внимание на то, что изменился сигнал сброса (`resetn_i`). Буква `n` на конце означает, что сброс работает по уровню `0` (когда сигнал равен нулю — это сброс, когда единице — не сброс).
|
||||
|
||||
Помимо прочего, необходимо подключить к вашему модулю `блок делителя частоты`. Поскольку в данном курсе лабораторных работ вы выполняли реализацию однотактного процессора, инструкция должна пройти через все ваши блоки за один такт. Из-за этого критический путь вашей схемы не позволит использовать тактовый сигнал частотой в `100 МГц`, от которого работает отладочный стенд. Поэтому, необходимо создать отдельный сигнал с пониженной тактовой частотой, от которого будет работать ваша схема.
|
||||
|
||||
Для этого необходимо:
|
||||
|
||||
1. Подключить файл [`sys_clk_rst_gen.sv`](sys_clk_rst_gen.sv) в ваш проект.
|
||||
2. Подключить этот модуль в начале описания модуля `riscv_unit` следующим образом:
|
||||
|
||||
```SystemVerilog
|
||||
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`.
|
||||
|
||||
---
|
||||
|
||||
## Задание
|
||||
|
||||
В рамках данной лабораторной работы необходимо реализовать модули-контроллеры двух периферийных устройств, реализующих управление в соответствии с приведенной ниже картой памяти и встроить их в процессорную систему, используя [_рис. 1_](../../.pic/Labs/lab_13_periph/fig_01.drawio.svg). На карте приведено шесть периферийных устройств, вам необходимо взять только два из них. Какие именно — сообщит преподаватель.
|
||||
|
||||

|
||||
|
||||
_Рисунок 2. Карта памяти периферийных устройств._
|
||||
|
||||
Работа с картой осуществляется следующим образом. Под названием каждого периферийного устройства указана старшая часть адреса (чему должны быть равны старшие 8 бит адреса, чтобы было сформировано обращение к данному периферийному устройству). Например, для переключателей это значение равно `0x01`, для светодиодов `0x02` и т.п.
|
||||
В самом левом столбце указаны используемые/неиспользуемые адреса в адресном пространстве данного периферийного устройства. Например для переключателей есть только один используемый адрес: `0x000000`. Его функциональное назначение и разрешения на доступ указаны в столбце соответствующего периферийного устройства. Возвращаясь к адресу `0x000000`, для переключателей мы видим следующее:
|
||||
|
||||
* **(R)** означает что разрешен доступ только на чтение (операция записи по этому адресу должна игнорироваться вашим контроллером).
|
||||
* **"Выставленное на переключателях значение"** означает ровно то, что и означает. Если процессор выполняет операцию чтения по адресу `0x01000000` (`0x01` [старшая часть адреса переключателей] + `0x000000` [младшая часть адреса для получения выставленного на переключателях значения]), то контроллер должен выставить на выходной сигнал `RD` значение на переключателях (о том как получить это значение будет рассказано чуть позже).
|
||||
|
||||
Рассмотрим еще один пример. При обращении по адресу `0x02000024` (`0x02` (старшая часть адреса контроллера светодиодов) + `0x000024` (младшая часть адреса для доступа на запись к регистру сброса) ) должна произойти запись в регистр сброса, который должен сбросить значения в регистре управления зажигаемых светодиодов и регистре управления режимом "моргания" светодиодов (подробнее о том как должны работать эти регистры будет ниже).
|
||||
|
||||
Таким образом, каждый контроллер периферийного устройства должен выполнять две вещи:
|
||||
|
||||
1. При получении сигнала `req_i`, записать в регистр или вернуть значение из регистра, ассоциированного с переданным адресом (адрес передается с обнуленной старшей частью). Если регистра, ассоциированного с таким адресом нет (например, для переключателей не ассоциировано ни одного адреса кроме `0x000000`), игнорировать эту операцию.
|
||||
2. Выполнять управление периферийным устройством с помощью управляющих регистров.
|
||||
|
||||
Подробное описание периферийных устройств их управления и назначение управляющих регистров будет дано после порядка выполнения задания.
|
||||
|
||||
---
|
||||
|
||||
## Порядок выполнения задания
|
||||
|
||||
1. Внимательно ознакомьтесь с [примером описания модуля контроллера](../../Basic%20Verilog%20structures/Controllers.md).
|
||||
2. Внимательно ознакомьтесь со спецификацией контроллеров периферии своего варианта. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
|
||||
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` входы и выходы периферии. **Необходимо добавить порты даже тех периферийных устройств, которые вы не будете реализовывать**.
|
||||
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` для ваших модулей-контроллеров.
|
||||
6. Проверьте работу процессорной системы с помощью моделирования.
|
||||
1. Для каждой пары контроллеров в папке `firmware/mem_files` представлены файлы, инициализирующие память инструкций. Обратите внимание, что для пары "PS2-VGA" также необходим файл, инициализирующий память данных (в модуле `ext_mem` необходимо прописать блок `$readmemh`).
|
||||
2. Исходный код программ с адресами и результирующими инструкциями находится в папке `firmware/software`.
|
||||
3. При моделировании светодиодов лучше уменьшить значение, до которого считает счетчик в режиме "моргания" в 10 раз, чтобы уменьшить время моделирования. Перед генерацией битстрима это значение будет необходимо восстановить.
|
||||
4. Для проверки тестбенч имитирует генерацию данных периферийных устройств ввода. При реализации контроллера клавиатуры или uart_rx рекомендуется ознакомиться с тем, какие именно данные тестбенч подает на вход.
|
||||
5. Для того, чтобы понять, что устройство работает должным образом, в первую очередь необходимо убедиться, что контроллер устройства ввода успешно осуществил прием данных (сгенерированные тестбенчем данные оказались в соответствующем регистре контроллера периферийного устройства) и сгенерировал запрос на прерывание.
|
||||
6. После чего, необходимо убедиться, что процессор среагировал на данное прерывание, и в процессе его обработки в контроллер устройства вывода были поданы выходные данные.
|
||||
7. Для того, чтобы лучше понимать как именно процессор будет обрабатывать прерывание, рекомендуется ознакомиться с исходным кодом исполняемой программы, расположенным в папке `firmware/software`.
|
||||
7. Переходить к следующему пункту можно только после того, как вы полностью убедились в работоспособности модуля на этапе моделирования (увидели корректные значения на выходных сигналах периферии, либо (если по сигналам периферии сложно судить о работоспособности), значениям в контрольных/статусных регистрах модуля-контроллера этой периферии). Генерация битстрима будет занимать у вас долгое время, а итогом вы получите результат: заработало / не заработало, без какой-либо дополнительной информации, поэтому без прочного фундамента на моделировании далеко уехать у вас не выйдет.
|
||||
<!-- 1. Для каждой пары контроллеров периферии предложено две программы: с обновлением данных по опросу и по прерываниям. Запустите моделирование сначала для одной программы, затем для другой (для этого необходимо обновить файл, инициализирующий память инструкций). После проверки работоспособности процессора, сравните поведение сигналов LSU для этих программ. -->
|
||||
8. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе.
|
||||
9. Проверьте работу вашей процессорной системы на отладочном стенде с ПЛИС.
|
||||
1. Обратите внимание, что в данной лабораторной уже не будет модуля верхнего уровня `nexys_...`, так как ваш модуль процессорной системы уже полностью самостоятелен и взаимодействует непосредственно с ножками ПЛИС через модули, управляемые контроллерами периферии.
|
||||
|
||||
---
|
||||
|
||||
## Описание контроллеров периферийных устройств
|
||||
|
||||
Для того, чтобы избежать избыточности в контексте описания контроллеров периферийных устройств будет использоваться два термина:
|
||||
|
||||
1. Под "**запросом на запись** по адресу `0xАДРЕС`" будет пониматься совокупность следующих условий:
|
||||
1. Происходит восходящий фронт `clk_i`.
|
||||
2. На входе `req_i` выставлено значение `1`.
|
||||
3. На входе `write_enable_i` выставлено значение `1`.
|
||||
4. На входе `addr_i` выставлено значение `0xАДРЕС`
|
||||
2. Под "**запросом на чтение** по адресу `0xАДРЕС`" будет пониматься совокупность следующих условий:
|
||||
1. На входе `req_i` выставлено значение `1`.
|
||||
2. На входе `write_enable_i` выставлено значение `0`.
|
||||
3. На входе `addr_i` выставлено значение `0xАДРЕС`
|
||||
|
||||
Обратите внимание на то, что **запрос на чтение** должен обрабатываться **синхронно** (выходные данные должны выдаваться по положительному фронту `clk_i`).
|
||||
|
||||
При описании поддерживаемых режимов доступа по данному адресу используется следующее обозначение:
|
||||
|
||||
* R — доступ **только на чтение**;
|
||||
* W — доступ **только на запись**;
|
||||
* RW — доступ на **чтение и запись**.
|
||||
|
||||
В случае отсутствия **запроса на чтение**, на выходе `read_data_o` не должно меняться значение (тоже самое было сделано в процессе разработки памяти данных).
|
||||
|
||||
Если пришел **запрос на запись** или **чтение**, это еще не значит, что контроллер должен его выполнить. В случае, если запрос происходит по адресу, не поддерживающему этот запрос (например **запрос на запись** по адресу, поддерживающему только чтение), данный запрос должен игнорироваться. В случае **запроса на чтение** по недоступному адресу, на выходе `read_data_o` должно остаться прежнее значение.
|
||||
|
||||
В случае осуществления записи по принятому запросу, необходимо записать данные с сигнала `write_data_i` в регистр, ассоциированный с адресом `addr_i` (если разрядность регистра меньше разрядности сигнала `write_data_i`, старшие биты записываемых данных отбрасываются).
|
||||
|
||||
В случае осуществления чтения по принятому запросу, необходимо по положительному фронту `clk_i` выставить данные с сигнала, ассоциированного с адресом `addr_i` на выходной сигнал `read_data_o` (если разрядность сигнала меньше разрядности выходного сигнала `read_data_o`, возвращаемые данные должны дополниться нулями в старших битах).
|
||||
|
||||
### Переключатели
|
||||
|
||||
Переключатели являются простейшим устройством ввода на отладочном стенде `Nexys A7`. Соответственно и контроллер, осуществляющий доступ процессора к ним так же будет очень простым. Рассмотрим прототип модуля, который вам необходимо реализовать:
|
||||
|
||||
```SystemVerilog
|
||||
module sw_sb_ctrl(
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к системной шине
|
||||
*/
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic req_i,
|
||||
input logic write_enable_i,
|
||||
input logic [31:0] addr_i,
|
||||
input logic [31:0] write_data_i, // не используется, добавлен для
|
||||
// совместимости с системной шиной
|
||||
output logic [31:0] read_data_o,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за отправку запросов на прерывание
|
||||
процессорного ядра
|
||||
*/
|
||||
|
||||
output logic interrupt_request_o,
|
||||
input logic interrupt_return_i,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к периферии
|
||||
*/
|
||||
input logic [15:0] sw_i
|
||||
);
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
По сути, логика работы контроллера сводится к тому, выдавать на шину `read_data_o` данные со входа `sw_i` каждый раз, когда приходит **запрос на чтение** по нулевому адресу. Поскольку разрядность `sw_i` в два раза меньше разрядности выхода `read_data_o` его старшие биты необходимо дополнить нулями.
|
||||
|
||||
Адресное пространство контроллера:
|
||||
|
||||
|Адрес|Режим доступа| Функциональное назначение |
|
||||
|-----|-------------|-------------------------------------------------|
|
||||
|0x00 | R | Чтение значения, выставленного на переключателях|
|
||||
|
||||
При этом, будучи устройством ввода, данный модуль может генерировать прерывание, чтобы сообщить процессору о том, что данные на переключателях были изменены. Если на очередном такте `clk_i` данные на входе `sw_i` изменились (т.е. отличаются от тех, что были на предыдущем такте), модуль должен выставить значение `1` на выходе `interrupt_request_o` и удерживать его до получения сигнала о завершении обработки прерывания `interrupt_return_i`.
|
||||
|
||||
Для отслеживания изменений на входе `sw_i` между тактами синхроимпульса вам потребуется вспомогательный регистр, каждый такт сохраняющий значение `sw_i`. При реализации данного регистра, не забывайте о том, что его необходимо сбрасывать посредством сигнала `rst_i`.
|
||||
|
||||
### Светодиоды
|
||||
|
||||
Как и переключатели, светодиоды являются простейшим устройством вывода. Поэтому, чтобы задание было интересней, для их управления был добавлен регистр, управляющий режимом вывода данных на светодиоды.
|
||||
Рассмотрим прототип модуля, который вам необходимо реализовать:
|
||||
|
||||
```SystemVerilog
|
||||
module led_sb_ctrl(
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к системной шине
|
||||
*/
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic req_i,
|
||||
input logic write_enable_i,
|
||||
input logic [31:0] addr_i,
|
||||
input logic [31:0] write_data_i,
|
||||
output logic [31:0] read_data_o,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к периферии
|
||||
*/
|
||||
output logic [15:0] led_o
|
||||
);
|
||||
|
||||
logic [15:0] led_val;
|
||||
logic led_mode;
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
Данный модуль должен выводить на выходной сигнал `led_o` данные с регистра `led_val`. Запись и чтение регистра `led_val` осуществляется по адресу `0x00`. Запись любого значения, превышающего `2¹⁶-1` должна игнорироваться.
|
||||
|
||||
Регистр `led_mode` отвечает за режим вывода данных на светодиоды. Когда этот регистр равен единице, светодиоды должны "моргать" выводимым значением. Под морганием подразумевается вывод значения из регистра `led_val` на выход `led_o` на одну секунду (загорится часть светодиодов, соответствующие которым биты шины `led_o` равны единице), после чего на одну секунду выход `led_o` необходимо подать нули. Запись и чтение регистра `led_mode` осуществляется по адресу `0x04`. Запись любого значения, отличного от `0` и `1` в регистр `led_mode` должна игнорироваться.
|
||||
|
||||
Отсчет времени можно реализовать простейшим счетчиком, каждый такт увеличивающимся на 1 и сбрасывающимся по достижении определенного значения, чтобы продолжить считать с нуля. Зная тактовую частоту, нетрудно определить до скольки должен считать счетчик. При тактовой частоте в 10 МГц происходит 10 миллионов тактов в секунду. Это означает, что при такой тактовой частоте через секунду счетчик будет равен `10⁷-1` (счет идет с нуля). Тем не менее удобней будет считать не до `10⁷-1` (что было бы достаточно очевидным и тоже правильным решением), а до `2*10⁷-1`. В этом случае старший бит счетчика каждую секунду будет инвертировать свое значение, что может быть использовано при реализации логики "моргания".
|
||||
|
||||
Важно отметить, что счетчик должен работать только при `led_mode == 1`, в противном случае счетчик должен быть равен нулю.
|
||||
|
||||
Обратите внимание на то, что адрес `0x24` является адресом сброса. В случае **запроса на запись** по этому адресу значения `1`. вы должны сбросить регистры `led_val`, `led_mode` и все вспомогательные регистры, которые вы создали. Для реализации сброса вы можете как создать отдельный регистр `led_rst`, в который будет происходить запись, а сам сброс будет происходить по появлению единицы в этом регистре (в этом случае необходимо не забыть сбрасывать и этот регистр), так и создать обычный провод, формирующий единицу в случае выполнения всех указанных условий (условий **запроса на запись**, адреса сброса и значения записываемых данных равному единице).
|
||||
|
||||
Адресное пространство контроллера:
|
||||
|
||||
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|
||||
|-----|-------------|-------------------|-----------------------------------------------------------------------------------|
|
||||
|0x00 | RW | [0:65535] | Чтение и запись в регистр `led_val` отвечающий за вывод данных на светодиоды |
|
||||
|0x04 | RW | [0:1] | Чтение и запись в регистр `led_mode`, отвечающий за режим "моргания" светодиодами |
|
||||
|0x24 | W | 1 | Запись сигнала сброса |
|
||||
|
||||
### Клавиатура PS/2
|
||||
|
||||
Клавиатура [PS/2](https://ru.wikipedia.org/wiki/PS/2_(порт)) осуществляет передачу [скан-кодов](https://ru.wikipedia.org/wiki/Скан-код), нажатых на этой клавиатуре клавиш.
|
||||
|
||||
В рамках данной лабораторной работы вам будет дан готовый модуль, осуществляющий прием данных с клавиатуры. От вас требуется написать лишь модуль, осуществляющий контроль предоставленным модулем. У готового модуля будет следующий прототип:
|
||||
|
||||
```SystemVerilog
|
||||
module PS2Receiver(
|
||||
input clk_i, // Сигнал тактирования процессора и вашего модуля-контроллера
|
||||
input kclk_i, // Тактовый сигнал, приходящий с клавиатуры
|
||||
input kdata_i, // Сигнал данных, приходящий с клавиатуры
|
||||
output [7:0] keycode_o, // Сигнал полученного с клавиатуры скан-кода клавиши
|
||||
output keycode_valid_o // Сигнал готовности данных на выходе keycodeout
|
||||
);
|
||||
endmodule
|
||||
```
|
||||
|
||||
Вам необходимо реализовать модуль-контроллер со следующим прототипом:
|
||||
|
||||
```SystemVerilog
|
||||
module ps2_sb_ctrl(
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к системной шине
|
||||
*/
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic [31:0] addr_i,
|
||||
input logic req_i,
|
||||
input logic [31:0] write_data_i,
|
||||
input logic write_enable_i,
|
||||
output logic [31:0] read_data_o,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за отправку запросов на прерывание
|
||||
процессорного ядра
|
||||
*/
|
||||
|
||||
output logic interrupt_request_o,
|
||||
input logic interrupt_return_i,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к модулю,
|
||||
осуществляющему прием данных с клавиатуры
|
||||
*/
|
||||
input logic kclk_i,
|
||||
input logic kdata_i
|
||||
);
|
||||
|
||||
logic [7:0] scan_code;
|
||||
logic scan_code_is_unread;
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
В первую очередь, вы должны создать экземпляр модуля `PS2Receiver` внутри вашего модуля-контроллера, соединив соответствующие входы. Для подключения к выходам необходимо создать дополнительные провода.
|
||||
|
||||
По каждому восходящему фронту сигнала `clk_i` вы должны проверять выход `keycode_valid_o` и, если тот равен единице, записать значение с выхода `keycode_o` в регистр `scan_code`. При этом значение регистра `scan_code_is_unread` необходимо выставить в единицу.
|
||||
|
||||
В случае, если произошел **запрос на чтение** по адресу `0x00`, необходимо выставить на выход `read_data_o` значение регистра `scan_code` (дополнив старшие биты нулями), при этом значение регистра `scan_code_is_unread` необходимо обнулить. В случае, если одновременно с **запросом на чтение** пришел сигнал `keycode_valid_o`, регистр `scan_code_is_unread` обнулять не нужно (в этот момент в регистр `scan_code` уже записывается новое, еще непрочитанное значение).
|
||||
|
||||
Обнуление регистра `scan_code_is_unread` должно происходить и в случае получения сигнала `interrupt_return_i` (однако опять же, если в этот момент приходит сигнал `keycode_valid_o`, обнулять регистр не нужно).
|
||||
|
||||
В случае **запроса на чтение** по адресу `0x04` необходимо вернуть значение регистра `scan_code_is_unread`.
|
||||
|
||||
В случае **запроса на запись** значения `1` по адресу `0x24`, необходимо осуществить сброс регистров `scan_code` и `scan_code_is_unread` в `0`.
|
||||
|
||||
Регистр `scan_code_is_unread` необходимо подключить к выходу `interrupt_request_o`. Таким образом процессор может узнавать о нажатых клавишах как посредством программного опроса путем чтения значения регистра`scan_code_is_unread`, так и посредством прерываний через сигнал`interrupt_request_o`.
|
||||
|
||||
Адресное пространство контроллера:
|
||||
|
||||
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|
||||
|-----|-------------|-------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
|0x00 | R | [0:255] | Чтение из регистра `scan_code`, хранящего скан-код нажатой клавиши |
|
||||
|0x04 | R | [0:1] | Чтение из регистра `scan_code_is_unread`, сообщающего о том, что есть непрочитанные данные в регистре `scan_code` |
|
||||
|0x24 | W | 1 | Запись сигнала сброса |
|
||||
|
||||
### Семисегментные индикаторы
|
||||
|
||||
Семисегментные индикаторы позволяют выводить арабские цифры и первые шесть букв латинского алфавита, тем самым позволяя отображать шестнадцатеричные цифры. На отладочном стенде `Nexys A7` размещено восемь семисегментных индикаторов. Для вывода цифр на эти индикаторы, вам будет предоставлен модуль `hex_digits`, вам нужно лишь написать модуль, осуществляющий контроль над ним. Прототип модуля `hex_digits` следующий:
|
||||
|
||||
```SystemVerilog
|
||||
module hex_digits(
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic [3:0] hex0_i, // Цифра, выводимой на нулевой (самый правый) индикатор
|
||||
input logic [3:0] hex1_i, // Цифра, выводимая на первый индикатор
|
||||
input logic [3:0] hex2_i, // Цифра, выводимая на второй индикатор
|
||||
input logic [3:0] hex3_i, // Цифра, выводимая на третий индикатор
|
||||
input logic [3:0] hex4_i, // Цифра, выводимая на четвертый индикатор
|
||||
input logic [3:0] hex5_i, // Цифра, выводимая на пятый индикатор
|
||||
input logic [3:0] hex6_i, // Цифра, выводимая на шестой индикатор
|
||||
input logic [3:0] hex7_i, // Цифра, выводимая на седьмой индикатор
|
||||
input logic [7:0] bitmask_i, // Битовая маска для включения/отключения
|
||||
// отдельных индикаторов
|
||||
|
||||
output logic [6:0] hex_led_o, // Сигнал, контролирующий каждый отдельный
|
||||
// светодиод индикатора
|
||||
output logic [7:0] hex_sel_o // Сигнал, указывающий на какой индикатор
|
||||
// выставляется hex_led
|
||||
);
|
||||
endmodule
|
||||
```
|
||||
|
||||
Для того, чтобы вывести шестнадцатеричную цифру на любой из индикаторов, необходимо выставить двоичное представление этой цифры на соответствующий вход `hex0-hex7`.
|
||||
|
||||
За включение/отключение индикаторов отвечает входной сигнал `bitmask_i`, состоящий из 8 бит, каждый из которых включает/отключает соответствующий индикатор. Например, при `bitmask_i == 8'b0000_0101`, включены будут нулевой и второй индикаторы, остальные будут погашены.
|
||||
|
||||
Выходные сигналы `hex_led` и `hex_sel` необходимо просто подключить к соответствующим выходным сигналам модуля-контроллера. Они пойдут на выходы ПЛИС, соединенные с семисегментными индикаторами.
|
||||
|
||||
Для управления данным модулем, необходимо написать модуль-контроллер со следующим прототипом:
|
||||
|
||||
```SystemVerilog
|
||||
module hex_sb_ctrl(
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к системной шине
|
||||
*/
|
||||
input logic clk_i,
|
||||
input logic [31:0] addr_i,
|
||||
input logic req_i,
|
||||
input logic [31:0] write_data_i,
|
||||
input logic write_enable_i,
|
||||
output logic [31:0] read_data_o,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к модулю,
|
||||
осуществляющему вывод цифр на семисегментные индикаторы
|
||||
*/
|
||||
output logic [6:0] hex_led,
|
||||
output logic [7:0] hex_sel
|
||||
);
|
||||
|
||||
logic [3:0] hex0, hex1, hex2, hex3, hex4, hex5, hex6, hex7;
|
||||
logic [7:0] bitmask;
|
||||
endmodule
|
||||
```
|
||||
|
||||
Регистры `hex0-hex7` отвечают за вывод цифры на соответствующий семисегментный индикатор. Регистр `bitmask` отвечает за включение/отключение семисегментных индикаторов. Когда в регистре `bitmask` бит, индекс которого совпадает с номером индикатора равен единице — тот включен и выводит число, совпадающее со значением в соответствующем регистре `hex0-hex7`. Когда бит равен нулю — этот индикатор гаснет.
|
||||
|
||||
Доступ на чтение/запись регистров `hex0-hex7` осуществляется по адресам `0x00-0x1c` (см. таблицу адресного пространства).
|
||||
|
||||
Доступ на чтение/запись регистра `bitmask` осуществляется по адресу `0x20`.
|
||||
|
||||
При **запросе на запись** единицы по адресу `0x24` необходимо выполнить сброс всех регистров. При этом регистр `bitmask` должен сброситься в значение `0xFF`.
|
||||
|
||||
Адресное пространство контроллера:
|
||||
|
||||
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|
||||
|-----|-------------|-------------------|---------------------------------------------------------|
|
||||
|0x00 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex0 |
|
||||
|0x04 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex1 |
|
||||
|0x08 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex2 |
|
||||
|0x0C | RW | [0:15] | Регистр, хранящий значение, выводимое на hex3 |
|
||||
|0x10 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex4 |
|
||||
|0x14 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex5 |
|
||||
|0x18 | RW | [0:15] | Регистр, хранящий значение, выводимое на hex6 |
|
||||
|0x1C | RW | [0:15] | Регистр, хранящий значение, выводимое на hex7 |
|
||||
|0x20 | RW | [0:255] | Регистр, управляющий включением/отключением индикаторов |
|
||||
|0x24 | W | 1 | Запись сигнала сброса |
|
||||
|
||||
### UART
|
||||
|
||||
[UART](https://ru.wikipedia.org/wiki/Универсальный_асинхронный_приёмопередатчик) — это последовательный интерфейс, использующий для приема и передачи данных по одной независимой линии с поддержкой контроля целостности данных.
|
||||
|
||||
Для того, чтобы передача данных была успешно осуществлена, приемник и передатчик на обоих концах одного провода должны договориться о параметрах передачи:
|
||||
|
||||
* её скорости (бодрейт);
|
||||
* контроля целостности данных (использование бита четности/нечетности/отсутствие контроля);
|
||||
* длины стопового бита.
|
||||
|
||||
Вам будут предоставлены модули, осуществляющие прием и передачу данных по этому интерфейсу, от вас лишь требуется написать модули, осуществляющие управление предоставленными модулями.
|
||||
|
||||
```SystemVerilog
|
||||
module uart_rx (
|
||||
input logic clk_i, // Тактирующий сигнал
|
||||
input logic rst_i, // Сигнал сброса
|
||||
input logic rx_i, // Сигнал линии, подключенной к выводу ПЛИС,
|
||||
// по которой будут приниматься данные
|
||||
output logic busy_o, // Сигнал о том, что модуль занят приемом данных
|
||||
input logic [16:0] baudrate_i, // Настройка скорости передачи данных
|
||||
input logic parity_en_i,// Настройка контроля целостности через бит четности
|
||||
input logic stopbit_i, // Настройка длины стопового бита
|
||||
output logic [7:0] rx_data_o, // Принятые данные
|
||||
output logic rx_valid_o // Сигнал о том, что прием данных завершен
|
||||
|
||||
);
|
||||
endmodule
|
||||
```
|
||||
|
||||
```SystemVerilog
|
||||
module uart_tx (
|
||||
input logic clk_i, // Тактирующий сигнал
|
||||
input logic rst_i, // Сигнал сброса
|
||||
output logic tx_o, // Сигнал линии, подключенной к выводу ПЛИС,
|
||||
// по которой будут отправляться данные
|
||||
output logic busy_o, // Сигнал о том, что модуль занят передачей данных
|
||||
input logic [16:0] baudrate_i, // Настройка скорости передачи данных
|
||||
input logic parity_en_i,// Настройка контроля целостности через бит четности
|
||||
input logic stopbit_i, // Настройка длины стопового бита
|
||||
input logic [7:0] tx_data_i, // Отправляемые данные
|
||||
input logic tx_valid_i // Сигнал о старте передачи данных
|
||||
);
|
||||
endmodule
|
||||
```
|
||||
|
||||
Для управления этими модулями вам необходимо написать два модуля-контроллера со следующими прототипами
|
||||
|
||||
```SystemVerilog
|
||||
module uart_rx_sb_ctrl(
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к системной шине
|
||||
*/
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic [31:0] addr_i,
|
||||
input logic req_i,
|
||||
input logic [31:0] write_data_i,
|
||||
input logic write_enable_i,
|
||||
output logic [31:0] read_data_o,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за отправку запросов на прерывание
|
||||
процессорного ядра
|
||||
*/
|
||||
|
||||
output logic interrupt_request_o,
|
||||
input logic interrupt_return_i,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение передающему,
|
||||
входные данные по UART
|
||||
*/
|
||||
input logic rx_i
|
||||
);
|
||||
|
||||
logic busy;
|
||||
logic [16:0] baudrate;
|
||||
logic parity_en;
|
||||
logic stopbit;
|
||||
logic [7:0] data;
|
||||
logic valid;
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
```SystemVerilog
|
||||
module uart_tx_sb_ctrl(
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к системной шине
|
||||
*/
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic [31:0] addr_i,
|
||||
input logic req_i,
|
||||
input logic [31:0] write_data_i,
|
||||
input logic write_enable_i,
|
||||
output logic [31:0] read_data_o,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение передающему,
|
||||
выходные данные по UART
|
||||
*/
|
||||
output logic tx_o
|
||||
);
|
||||
|
||||
logic busy;
|
||||
logic [16:0] baudrate;
|
||||
logic parity_en;
|
||||
logic stopbit;
|
||||
logic [7:0] data;
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
У обоих предоставленных модулей схожий прототип, различия заключаются лишь в направлениях сигналов `data` и `valid`.
|
||||
|
||||
Взаимодействие модулей `uart_rx` и `uart_tx` с соответствующими модулями-контроллерами осуществляется следующим образом.
|
||||
|
||||
Сигналы `clk_i` и `rx_i`/`tx_o` подключаются напрямую к соответствующим сигналам модулей-контроллеров.
|
||||
|
||||
Сигнал `rst_i` модулей `uart_rx` / `uart_tx` должен быть равен единице при **запросе на запись** единицы по адресу `0x24`, а также в случае, когда сигнал `rst_i` модуля-контроллера равен единице.
|
||||
|
||||
Выходной сигнал `busy_o` на каждом такте `clk_i` должен записываться в регистр `busy`, доступ на чтение к которому осуществляется по адресу `0x08`.
|
||||
|
||||
Значения входных сигналов `baudrate_i`, `parity_en_i`, `stopbit_i` берутся из соответствующих регистров, доступ на запись к которым осуществляется по адресам `0x0C`, `0x10`, `0x14` соответственно, но только в моменты, когда выходной сигнал `busy_o` равен нулю. Иными словами, изменение настроек передачи возможно только в моменты, когда передача не происходит. Доступ на чтение этих регистров может осуществляться в любой момент времени.
|
||||
|
||||
В регистр `data` модуля `uart_rx_sb_ctrl` записывается значение одноименного выхода модуля `uart_rx` в моменты положительного фронта `clk_i`, когда сигнал `rx_valid_o` равен единице. Доступ на чтение этого регистра осуществляется по адресу `0x00`.
|
||||
|
||||
В регистр `valid` модуля `uart_rx_sb_ctrl` записывается единица по положительному фронту clk_i, когда выход `rx_valid_o` равен единице. Данный регистр сбрасывается в ноль при выполнении **запроса на чтение** по адресу `0x00`, а также при получении сигнала `interrupt_return_i`. Сам регистр доступен для чтения по адресу `0x04`. Регистр `valid` подключается к выходу `interrupt_request_o`. Что позволяет узнать о пришедших данных и посредством прерывания.
|
||||
|
||||
На вход `tx_data_i` модуля `uart_tx` подаются данные из регистра `data` модуля `uart_tx_sb_ctrl`. Доступ на запись в этот регистр происходит по адресу `0x00` в моменты положительного фронта `clk_i`, когда сигнал `busy_o` равен нулю. Доступ на чтение этого регистра может осуществляться в любой момент времени.
|
||||
|
||||
На вход `tx_valid_i` модуля `uart_tx` подается единица в момент выполнения **запроса на запись** по адресу `0x00` (при сигнале `busy` равном нулю). В остальное время на вход этого сигнала подается `0`.
|
||||
|
||||
В случае **запроса на запись** значения `1` по адресу `0x24` (адресу сброса), все регистры модуля-контроллера должны сброситься. При этом регистр `baudrate` должен принять значение `9600`, регистр `parity` должен принять значение `1`, регистр, `stopbit` должен принять значение `1`. Остальные регистры должны принять значение `0`.
|
||||
|
||||
Адресное пространство контроллера `uart_rx_sb_ctrl`:
|
||||
|
||||
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|
||||
|-----|-------------|-------------------|---------------------------------------------------------------------------------------------------------|
|
||||
|0x00 | R | [0:255] | Чтение из регистра `data`, хранящего значение принятых данных |
|
||||
|0x04 | R | [0:1] | Чтение из регистра `valid`, сообщающего о том, что есть непрочитанные данные в регистре `data` |
|
||||
|0x08 | R | [0:1] | Чтение из регистра `busy`, сообщающего о том, что модуль находится в процессе приема данных |
|
||||
|0x0C | RW | [0:65535] | Чтение/запись регистра `baudrate`, отвечающего за скорость передачи данных |
|
||||
|0x10 | RW | [0:1] | Чтение/запись регистра `parity`, отвечающего за включение отключение проверки данных через бит четности |
|
||||
|0x14 | RW | [0:1] | Чтение/запись регистра `stopbit`, отвечающего за длину стопового бита |
|
||||
|0x24 | W | 1 | Запись сигнала сброса |
|
||||
|
||||
Адресное пространство контроллера `uart_tx_sb_ctrl`:
|
||||
|
||||
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|
||||
|-----|-------------|-------------------|---------------------------------------------------------------------------------------------------------|
|
||||
|0x00 | RW | [0:255] | Чтение и запись регистра `data`, хранящего значение отправляемых данных |
|
||||
|0x08 | R | [0:1] | Чтение из регистра `busy`, сообщающего о том, что модуль находится в процессе передачи данных |
|
||||
|0x0C | RW | [0:65535] | Чтение/запись регистра `baudrate`, отвечающего за скорость передачи данных |
|
||||
|0x10 | RW | [0:1] | Чтение/запись регистра `parity`, отвечающего за включение отключение проверки данных через бит четности |
|
||||
|0x14 | RW | [0:1] | Чтение/запись регистра `stopbit`, отвечающего за длину стопового бита |
|
||||
|0x24 | W | 1 | Запись сигнала сброса |
|
||||
|
||||
### Видеоадаптер
|
||||
|
||||
Видеоадаптер позволяет выводить информацию на экран через интерфейс **VGA**. Предоставляемый в данной лабораторной работе vga-модуль способен выводить `80х30` символов (разрешение символа `8x16`). Таким образом, итоговое разрешение экрана, поддерживаемого vga-модулем будет `80*8 x 30*16 = 640x480`. VGA-модуль поддерживает управление цветовой схемой для каждого поля символа в сетке `80х30`. Это значит, что каждый символ (и фон символа) может быть отрисован отдельным цветом из диапазона 16-ти цветов.
|
||||
|
||||

|
||||
|
||||
_Рисунок 3. Пример игры с использованием символьной графики[[2]](https://en.wikipedia.org/wiki/Rebelstar)._
|
||||
|
||||
Для управления выводимым на экран содержимым, адресное пространство модуля разделено на следующие диапазоны:
|
||||
|
||||

|
||||
|
||||
_Рисунок 4. Карта памяти vga-модуля._
|
||||
|
||||
Для того, чтобы вывести символ на экран, необходимо использовать адрес этого символа на сетке `80x30` (диапазон адресов `char_map`). К примеру, мы хотим вывести символ в верхнем левом углу. Это нулевой символ в диапазоне адресов `char_map`. Поскольку данный диапазон начинается с адреса `0x0000_0000`, запись по этому адресу приведет к отображению символа, соответствующего [ASCII-коду](https://www.asciitable.com/), пришедшему на `write_data_i`.
|
||||
|
||||
Если мы хотим вывести нулевой (левый) символ в первой строке (счет ведется с нуля), то необходимо произвести запись по адресу `1*80 + 0 = 80 = 0x0000_0050`.
|
||||
|
||||
Вывод символа в правом нижнем углу осуществляется записью по адресу `0x0000_095F` (80*30-1)
|
||||
|
||||
Установка цветовой схемы осуществляется по тем же самым адресам, к которым прибавлено значение `0x0000_1000`:
|
||||
|
||||
* верхний левый символ — `0x0000_1000`
|
||||
* нулевой символ первой строки — `0x0000_1050`
|
||||
* нижний правый символ — `0x0000_195F`
|
||||
|
||||
Цветовая схема каждой позиции состоит из двух цветов: цвета фона и цвета символа. Оба эти цвета выбираются из палитры 8 цветов, каждый из которых содержит два оттенка: цвет на полной яркости и цвет на уменьшенной яркости (см. рис. 5). Один из цветов — черный, оба его оттенка представляют собой один и тот же цвет. Ниже приведены коды цветов их rgb-значения:
|
||||
|
||||

|
||||
|
||||
_Рисунок 5. Цветовая палитра vga-модуля._
|
||||
|
||||
Код цвета формируется следующим образом: старший бит определяет яркость оттенка цвета. Оставшиеся 3 бита кодируют используемый канал:
|
||||
|
||||
* 0 бит кодирует использование синего канала;
|
||||
* 1 бит кодирует использование зеленого канала;
|
||||
* 2 бит кодирует использование красного канала.
|
||||
|
||||
Таким образом, для установки цветовой схемы, необходимо выбрать два цвета из палитры, склеить их (в старших разрядах идет цвет символа, в младших — цвет фона) и записать получившееся 8-битное значение по адресу выбранной позиции в диапазоне адресов цветовой схемы (color_map).
|
||||
|
||||
К примеру, мы хотим установить черный фоновый цвет и белый цвет в качестве цвета символа для верхней левой позиции. В этом случае, мы должны записать значение `f0` (f(15) — код белого цвета, 0 — код черного цвета) по адресу `0x0000_1000` (нулевой адрес в диапазоне `color_map`).
|
||||
|
||||
Для отрисовки символов, мы условно поделили экран на сетку `80х30`, и для каждой позиции в этой сетке определили фоновый и активный цвет. Чтобы модуль мог отрисовать символ на очередной позиции (которая занимает `16х8` пикселей), ему необходимо знать в какой цвет необходимо окрасить каждый пиксель для каждого ascii-кода. Для этого используется память шрифтов.
|
||||
|
||||
Допустим, нам необходимо отрисовать символ `F` (ascii-код `0x46`).
|
||||
|
||||

|
||||
_Рисунок 6. Отрисовка символа `F` в разрешении 16х8 пикселей._
|
||||
|
||||
Данный символ состоит из 16 строчек по 8 пикселей. Каждый пиксель кодируется одним битом (горит/не горит, цвет символа/фоновый цвет). Каждая строчка кодируется одним байтом (8 бит на 8 пикселей). Таким образом, каждый сканкод требует 16 байт памяти.
|
||||
|
||||
Данный модуль поддерживает 256 сканкодов. Следовательно, для хранения шрифта под каждый из 256 сканкодов требуется 16 * 256 = 4KiB памяти.
|
||||
|
||||
Для хранения шрифтов в модуле отведен диапазон адресов `0x00002000-0x00002FFF`. В отличие от предыдущих диапазонов адресов, где каждый адрес был закреплен за соответствующей позицией символа в сетке `80x30`, адреса данного диапазона распределены следующим образом:
|
||||
|
||||
* 0-ой байт — нулевая (верхняя) строчка символа с кодом 0;
|
||||
* 1-ый байт — первая строчка символа с кодом 0;
|
||||
* ...
|
||||
* 15-ый байт — пятнадцатая (нижняя) строчка символа с кодом 0;
|
||||
* 16-ый байт — нулевая (верхняя) строчка символа с кодом 1;
|
||||
* ...
|
||||
* 4095-ый байт — пятнадцатая (нижняя) строчка символа с кодом 255.
|
||||
|
||||
Прототип vga-модуля следующий:
|
||||
|
||||
```SystemVerilog
|
||||
module vgachargen (
|
||||
input logic clk_i, // системный синхроимпульс
|
||||
input logic clk100m_i, // клок с частотой 100МГц
|
||||
input logic rst_i, // сигнал сброса
|
||||
|
||||
/*
|
||||
Интерфейс записи выводимого символа
|
||||
*/
|
||||
input logic [ 9:0] char_map_addr_i, // адрес позиции выводимого символа
|
||||
input logic char_map_we_i, // сигнал разрешения записи кода
|
||||
input logic [ 3:0] char_map_be_i, // сигнал выбора байтов для записи
|
||||
input logic [31:0] char_map_wdata_i, // ascii-код выводимого символа
|
||||
output logic [31:0] char_map_rdata_o, // сигнал чтения кода символа
|
||||
|
||||
/*
|
||||
Интерфейс установки цветовой схемы
|
||||
*/
|
||||
input logic [ 9:0] col_map_addr_i, // адрес позиции устанавливаемой схемы
|
||||
input logic col_map_we_i, // сигнал разрешения записи схемы
|
||||
input logic [ 3:0] col_map_be_i, // сигнал выбора байтов для записи
|
||||
input logic [31:0] col_map_wdata_i, // код устанавливаемой цветовой схемы
|
||||
output logic [31:0] col_map_rdata_o, // сигнал чтения кода схемы
|
||||
|
||||
/*
|
||||
Интерфейс установки шрифта
|
||||
*/
|
||||
input logic [ 9:0] char_tiff_addr_i, // адрес позиции устанавливаемого шрифта
|
||||
input logic char_tiff_we_i, // сигнал разрешения записи шрифта
|
||||
input logic [ 3:0] char_tiff_be_i, // сигнал выбора байтов для записи
|
||||
input logic [31:0] char_tiff_wdata_i,// отображаемые пиксели в текущей позиции шрифта
|
||||
output logic [31:0] char_tiff_rdata_o,// сигнал чтения пикселей шрифта
|
||||
|
||||
|
||||
output logic [3:0] vga_r_o, // красный канал vga
|
||||
output logic [3:0] vga_g_o, // зеленый канал vga
|
||||
output logic [3:0] vga_b_o, // синий канал vga
|
||||
output logic vga_hs_o, // линия горизонтальной синхронизации vga
|
||||
output logic vga_vs_o // линия вертикальной синхронизации vga
|
||||
);
|
||||
```
|
||||
|
||||
Файлы модуля:
|
||||
|
||||
* peripheral modules/vhachargen.sv
|
||||
* peripheral modules/vhachargen_pkg.sv
|
||||
* firmware/mem_files/lab_12_ps2_vga_instr.mem — этим файлом необходимо проинициализировать память инструкций
|
||||
* firmware/mem_files/lab_12_ps2ascii_data.mem — этим файлом необходимо проинициализировать память данных
|
||||
* firmware/mem_files/lab_12_vga_ch_map.mem
|
||||
* firmware/mem_files/lab_12_vga_ch_t_ro.mem
|
||||
* firmware/mem_files/lab_12_vga_ch_t_rw.mem
|
||||
* firmware/mem_files/lab_12_vga_col_map.mem
|
||||
|
||||
Вам необходимо добавить в проект все эти файлы.
|
||||
|
||||
Для управления данным модулем, необходимо написать модуль-контроллер со следующим прототипом:
|
||||
|
||||
```SystemVerilog
|
||||
module vga_sb_ctrl (
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic clk100m_i,
|
||||
input logic req_i,
|
||||
input logic write_enable_i,
|
||||
input logic [3:0] mem_be_i,
|
||||
input logic [31:0] addr_i,
|
||||
input logic [31:0] write_data_i,
|
||||
output logic [31:0] read_data_o,
|
||||
|
||||
output logic [3:0] vga_r_o,
|
||||
output logic [3:0] vga_g_o,
|
||||
output logic [3:0] vga_b_o,
|
||||
output logic vga_hs_o,
|
||||
output logic vga_vs_o
|
||||
);
|
||||
```
|
||||
|
||||
Реализация данного модуля исключительно простая. В первую очередь необходимо подключить одноименные сигналы напрямую:
|
||||
|
||||
* `clk_i`,
|
||||
* `rst_i`,
|
||||
* `clk100m_i`,
|
||||
* `vga_r_o`,
|
||||
* `vga_g_o`,
|
||||
* `vga_b_o`,
|
||||
* `vga_hs_o`,
|
||||
* `vga_vs_o`
|
||||
|
||||
Кроме того, необходимо:
|
||||
|
||||
1. подключить напрямую сигнал `write_data_i` ко входам:
|
||||
1. `char_map_wdata_i`,
|
||||
2. `col_map_wdata_i`,
|
||||
3. `char_tff_wdata_i`,
|
||||
2. подключить биты `addr_i[11:2]` ко входам:
|
||||
1. `char_map_addr_i`,
|
||||
2. `col_map_addr_i`,
|
||||
3. `char_tiff_addr_i`,
|
||||
3. сигнал `mem_be_i` подключить ко входам:
|
||||
1. `char_map_be_i`,
|
||||
2. `col_map_be_i`,
|
||||
3. `char_tiff_be_i`.
|
||||
|
||||
Остается только разобраться с сигналами `write_enable_i` и `read_data_o`.
|
||||
|
||||
Оба эти сигнала мультиплексируются / демультиплексируются с помощью одного и того же управляющего сигнала: `addr_i[13:12]` в соответствии с диапазонами адресов (рис. 4):
|
||||
|
||||
* `addr_i[13:12] == 2'b00` — сигнал `write_enable_i` поступает на вход `char_map_we_i`, выход `char_map_rdata_o` записывается в выходной регистр `read_data_o`;
|
||||
* `addr_i[13:12] == 2'b01` — сигнал `write_enable_i` поступает на вход `col_map_we_i`, выход `col_map_rdata_o` записывается в выходной регистр `read_data_o`;
|
||||
* `addr_i[13:12] == 2'b10` — сигнал `write_enable_i` поступает на вход `char_tiff_we_i`, выход `char_tiff_rdata_o` записывается в выходной регистр `read_data_o`.
|
||||
|
||||
## Список использованной литературы
|
||||
|
||||
1. С.А. Орлов, Б.Я. Цилькер / Организация ЭВМ и систем: Учебник для вузов. 2-е изд. / СПб.: Питер, 2011.
|
||||
2. [Rebelstar](https://en.wikipedia.org/wiki/Rebelstar)
|
@@ -0,0 +1,599 @@
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
||||
5f5e5d5c
|
||||
63626160
|
||||
67666564
|
||||
6b6a6968
|
||||
6f6e6d6c
|
||||
73727170
|
||||
77767574
|
||||
7b7a7978
|
||||
7f7e7d7c
|
||||
03020100
|
||||
07060504
|
||||
0b0a0908
|
||||
0f0e0d0c
|
||||
13121110
|
||||
17161514
|
||||
1b1a1918
|
||||
1f1e1d1c
|
||||
23222120
|
||||
27262524
|
||||
2b2a2928
|
||||
2f2e2d2c
|
||||
33323130
|
||||
37363534
|
||||
3b3a3938
|
||||
3f3e3d3c
|
||||
43424140
|
||||
47464544
|
||||
4b4a4948
|
||||
4f4e4d4c
|
||||
53525150
|
||||
57565554
|
||||
5b5a5958
|
@@ -0,0 +1,128 @@
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00011110000100000001000000010000000100000001000000010000000100000001000000010000000111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000010000000100000000000000010000000100000001000000010000000100000001000000010000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000101000001010000000000000000
|
||||
00000000000000000000000000000000000100100001001000111111000100100001001000010010001111110001001000010010000000000000000000000000
|
||||
00000000000000000000000000000100000011100001000100010001000100000001000000001110000000010001000100010001000011100000010000000000
|
||||
00000000000000000000000000100000010100000101000100100010000001000000100000010000001000100100010100000101000000100000000000000000
|
||||
00000000000000000000000000000000010011100011000100100001001100010100101001001100000100100001001000010010000011000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000010000000100000000000000000
|
||||
00000000000000000000000000000100000000100000000100000001000000010000000100000001000000010000000100000010000001000000000000000000
|
||||
00000000000000000000000000000001000000100000010000000100000001000000010000000100000001000000010000000010000000010000000000000000
|
||||
00000000000000000000000000000000000000000000000000010010000011000011111100001100000100100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000100000001000001111100000100000001000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000001000000100000001000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000111100000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000010000000100000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000010000000100000010000000100000010000000100000010000000100000010000000100000000000000000000
|
||||
00000000000000000000000000000000000111100010000100100011001001010010010100101001001010010011000100100001000111100000000000000000
|
||||
00000000000000000000000000000000000010000000100000001000000010000000100000001000000010010000101000001100000010000000000000000000
|
||||
00000000000000000000000000000000001111110000000100000001000000100000010000001000000100000010000000100001000111100000000000000000
|
||||
00000000000000000000000000000000000111100010000100100000001000000010000000011100001000000010000000100001000111100000000000000000
|
||||
00000000000000000000000000000000000100000001000000010000000100000011111100010001000100100001010000011000000100000000000000000000
|
||||
00000000000000000000000000000000000111100010000100100000001000000010000000011111000000010000000100000001001111110000000000000000
|
||||
00000000000000000000000000000000000111100010000100100001001000010010000100011111000000010000000100000010000111000000000000000000
|
||||
00000000000000000000000000000000000001000000010000000100000001000000100000010000001000000010000000100000001111110000000000000000
|
||||
00000000000000000000000000000000000111100010000100100001001000010010000100011110001000010010000100100001000111100000000000000000
|
||||
00000000000000000000000000000000000111100010000100100000001000000010000000111110001000010010000100100001000111100000000000000000
|
||||
00000000000000000000000000000000000000010000000100000000000000000000000000000001000000010000000000000000000000000000000000000000
|
||||
00000000000000000000000000000001000000100000001000000000000000000000000000000010000000100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000100000000100000000100000000100000000100000010000001000000100000010000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000001111110000000000111111000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000010000001000000100000010000001000000001000000001000000001000000001000000000000000000000000
|
||||
00000000000000000000000000000000000001000000010000000000000001000000100000010000001000000010000100100001000111100000000000000000
|
||||
00000000000000000000000000000000011111000000001001111001101001011011100110100001100110010100001000111100000000000000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001001000010011111100100001001000010010000100100001000111100000000000000000
|
||||
00000000000000000000000000000000000111110010000100100001001000010010000100011111001000010010000100100001000111110000000000000000
|
||||
00000000000000000000000000000000000111100010000100000001000000010000000100000001000000010000000100100001000111100000000000000000
|
||||
00000000000000000000000000000000000011110001000100100001001000010010000100100001001000010010000100010001000011110000000000000000
|
||||
00000000000000000000000000000000001111110000000100000001000000010000000100001111000000010000000100000001001111110000000000000000
|
||||
00000000000000000000000000000000000000010000000100000001000000010000000100001111000000010000000100000001001111110000000000000000
|
||||
00000000000000000000000000000000000111100010000100100001001000010011100100000001000000010000000100100001000111100000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001001000010010000100111111001000010010000100100001001000010000000000000000
|
||||
00000000000000000000000000000000000000010000000100000001000000010000000100000001000000010000000100000001000000010000000000000000
|
||||
00000000000000000000000000000000000111100010000100100001001000000010000000100000001000000010000000100000001000000000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001000100010000100100000111000010010001000100100001001000010000000000000000
|
||||
00000000000000000000000000000000001111110000000100000001000000010000000100000001000000010000000100000001000000010000000000000000
|
||||
00000000000000000000000000000000010000010100000101000001010000010100000101001001010010010101010101100011010000010000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001001000010010000100110001001010010010010100100011001000010000000000000000
|
||||
00000000000000000000000000000000000111100010000100100001001000010010000100100001001000010010000100100001000111100000000000000000
|
||||
00000000000000000000000000000000000000010000000100000001000000010000000100011111001000010010000100100001000111110000000000000000
|
||||
00000000000000000000000000100000001111100011000100101001001000010010000100100001001000010010000100100001000111100000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001001000010001000100011111001000010010000100100001000111110000000000000000
|
||||
00000000000000000000000000000000000111100010000100100000001000000001000000001100000000100000000100100001000111100000000000000000
|
||||
00000000000000000000000000000000000010000000100000001000000010000000100000001000000010000000100000001000011111110000000000000000
|
||||
00000000000000000000000000000000000111100010000100100001001000010010000100100001001000010010000100100001001000010000000000000000
|
||||
00000000000000000000000000000000000010000000100000010100000101000010001000100010010000010100000101000001010000010000000000000000
|
||||
00000000000000000000000000000000010000010110001101010101010010010100100101001001010000010100000101000001010000010000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001000100100000110000001100000100100010000100100001001000010000000000000000
|
||||
00000000000000000000000000000000000010000000100000001000000010000000100000010100001000100010001001000001010000010000000000000000
|
||||
00000000000000000000000000000000001111110000000100000001000000100000010000001000000100000010000000100000001111110000000000000000
|
||||
00000000000000000000000000000111000000010000000100000001000000010000000100000001000000010000000100000001000001110000000000000000
|
||||
00000000000000000000000000000000000100000001000000001000000010000000010000000100000000100000001000000001000000010000000000000000
|
||||
00000000000000000000000000000111000001000000010000000100000001000000010000000100000001000000010000000100000001110000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001000010100000010000000000
|
||||
00000000000000000011111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000001000000010000000000000000
|
||||
00000000000000000000000000000000001111100010000100100001001000010011111000100000000111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000111110010000100100001001000010010000100100001000111110000000100000001000000010000000000000000
|
||||
00000000000000000000000000000000000111100010000100000001000000010000000100100001000111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000001111100010000100100001001000010010000100100001001111100010000000100000001000000000000000000000
|
||||
00000000000000000000000000000000000111100010000100000001001111110010000100100001000111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000100000001000000010000000100000001000001111000000100000001000100010000111000000000000000000
|
||||
00000000000111100010000100100000001011100011000100100001001000010010000100100001000111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001001000010010000100100001000111110000000100000001000000010000000000000000
|
||||
00000000000000000000000000000000000000010000000100000001000000010000000100000001000000010000000000000001000000000000000000000000
|
||||
00000000000011100001000100010001000100000001000000010000000100000001000000010000000100000000000000010000000000000000000000000000
|
||||
00000000000000000000000000000000001000010010000100010001000011110001000100100001001000010000000100000001000000010000000000000000
|
||||
00000000000000000000000000000000000000100000000100000001000000010000000100000001000000010000000100000001000000010000000000000000
|
||||
00000000000000000000000000000000010000010100100101001001010010010100100101001001001101110000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000001000010010000100100001001000010010000100100001000111110000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000111100010000100100001001000010010000100100001000111100000000000000000000000000000000000000000
|
||||
00000000000000010000000100000001000111110010000100100001001000010010000100100001000111110000000000000000000000000000000000000000
|
||||
00000000001000000010000000100000001111100010000100100001001000010010000100100001001111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000010000000100000001000000010000000100000011000111010000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000111100010000100100000000111100000000100100001000111100000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000110000000010000000100000001000000010000000100000111110000010000000100000000000000000000000000
|
||||
00000000000000000000000000000000001111100010000100100001001000010010000100100001001000010000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000010000001010000010100001000100010001001000001010000010000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000001000100101010101001001010010010100100101000001010000010000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000010000010010001000010100000010000001010000100010010000010000000000000000000000000000000000000000
|
||||
00000000000011110001000000100000001011100011000100100001001000010010000100100001001000010000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000001111110000000100000010000001000000100000010000001111110000000000000000000000000000000000000000
|
||||
00000000000000000000000000011000000001000000010000000100000001000000001100000100000001000000010000000100000110000000000000000000
|
||||
00000000000000000000000000000000000000010000000100000001000000010000000100000000000000010000000100000001000000010000000000000000
|
||||
00000000000000000000000000000011000001000000010000000100000001000001100000000100000001000000010000000100000000110000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011001001001100000000000000000
|
||||
00000000000000000000000001100000001000000010000000101100000001000000110000001100000000000000001100000101000001010000001100000000
|
@@ -0,0 +1,33 @@
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000010010000100111111001000010001001000010010000011000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000111110010000100100001000111110000000100000001000111110
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000111110010000100100001000111110001000100010001000011110
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000001000000010000000100000001001111110
|
||||
00000000000000000000000000000000000000000000000000000000000000000100000101111111001000010010001000100010001001000010010000111100
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001111110000000100000001000011110000000100000001001111110
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001111110000000100000001000011110000000100111111000100100
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001001001010010010010101000011100001010100100100101001001
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000111100010000100100000000111000010000000100010000111000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000110010010100100101001010010010100100110001001100010
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000110010010100101001001100010010000100001100000100100
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000010001000100010001000011110000010100001001000100010
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000010010000100100010001000100010010000100100001111000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001001001010010010101010101010101011000110110001101000001
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000010010000100100001001111110010000100100001001000010
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000011100001000100100001001000010010000100100010000111000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000010010000100100001001000010010000100100001001111110
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000010000000100001111000100010010000100100001000111110
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000111000010001000000001000000010000000100100010000111000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000100000001000000010000000100001111111
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000010000001000000100000011000001001000100001001000010
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000001000001111100100100101001001010010010011111000001000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000010010000100010010000011000001001000100001001000010
|
||||
00000000000000000000000000000000000000000000000000000000000000000100000001111110001000100010001000100010001000100010001000100010
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000000010000000101110001100010010000100100001001000010
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001111111010010010100100101001001010010010100100101001001
|
||||
00000000000000000000000000000000000000000000000000000000000000000100000001111111010010010100100101001001010010010100100101001001
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000111100010001000100010001000100001111000000010000000111
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001001111010100010101000101010001010011110100000101000001
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000011110001000100010001000100010000111100000001000000010
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000011100001000100100000001111000010000000010001000011100
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000011001001001010100010101000111010001010100100100110001
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000001000010010001000111110001000010010000100100010001111000
|
@@ -0,0 +1,600 @@
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
||||
a0a0a0a0
|
@@ -0,0 +1,43 @@
|
||||
030000b7
|
||||
04000137
|
||||
0e000193
|
||||
0f000213
|
||||
00e00413
|
||||
00f00493
|
||||
00000593
|
||||
00100293
|
||||
30429073
|
||||
03400293
|
||||
00028293
|
||||
30529073
|
||||
00000063
|
||||
0000a383
|
||||
04338263
|
||||
04438c63
|
||||
00700333
|
||||
00435313
|
||||
00612223
|
||||
00f3f393
|
||||
00712023
|
||||
00b04c63
|
||||
00012a23
|
||||
00012823
|
||||
00012623
|
||||
00012423
|
||||
00300513
|
||||
000005b3
|
||||
00356513
|
||||
02a12023
|
||||
30200073
|
||||
00812a23
|
||||
00012823
|
||||
03056513
|
||||
02a12023
|
||||
00158593
|
||||
30200073
|
||||
00912623
|
||||
00012423
|
||||
00c56513
|
||||
02a12023
|
||||
00158593
|
||||
30200073
|
@@ -0,0 +1,17 @@
|
||||
030000b7
|
||||
07000137
|
||||
070011b7
|
||||
96018193
|
||||
00100293
|
||||
30429073
|
||||
02400293
|
||||
30529073
|
||||
00000063
|
||||
0000a383
|
||||
00038403
|
||||
00810023
|
||||
00110113
|
||||
00315463
|
||||
30200073
|
||||
07000137
|
||||
30200073
|
@@ -0,0 +1,23 @@
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
007E0900
|
||||
00000000
|
||||
00317100
|
||||
737A0000
|
||||
00327761
|
||||
64786300
|
||||
00333465
|
||||
66762000
|
||||
00357274
|
||||
68626E00
|
||||
00367967
|
||||
6A6D0000
|
||||
00383775
|
||||
696B2C00
|
||||
0039306F
|
||||
6C2F2E00
|
||||
002D703B
|
||||
00270000
|
||||
00003D5B
|
||||
5D0D0000
|
@@ -0,0 +1,20 @@
|
||||
050000b7
|
||||
04000137
|
||||
0001c1b7
|
||||
20018193
|
||||
0030a623
|
||||
00100213
|
||||
0040a823
|
||||
00100293
|
||||
30429073
|
||||
03400293
|
||||
00028293
|
||||
30529073
|
||||
00000063
|
||||
0000a383
|
||||
00700333
|
||||
00435313
|
||||
00612223
|
||||
00f3f393
|
||||
00712023
|
||||
30200073
|
@@ -0,0 +1,31 @@
|
||||
050000b7
|
||||
02000137
|
||||
0001c1b7
|
||||
20018193
|
||||
0030a623
|
||||
00100213
|
||||
0040a823
|
||||
000011b7
|
||||
d0d18193
|
||||
00008237
|
||||
f7f20213
|
||||
0ff00493
|
||||
00100313
|
||||
00100293
|
||||
30429073
|
||||
04c00293
|
||||
00028293
|
||||
30529073
|
||||
00000063
|
||||
0000a383
|
||||
00947433
|
||||
00841413
|
||||
00746433
|
||||
00340863
|
||||
00440a63
|
||||
00812023
|
||||
30200073
|
||||
00612223
|
||||
30200073
|
||||
02612223
|
||||
30200073
|
@@ -0,0 +1,18 @@
|
||||
050000b7
|
||||
06000137
|
||||
0001c1b7
|
||||
20018193
|
||||
0030a623
|
||||
00312623
|
||||
00100213
|
||||
0040a823
|
||||
00412823
|
||||
00100293
|
||||
30429073
|
||||
03c00293
|
||||
00028293
|
||||
30529073
|
||||
00000063
|
||||
0000a383
|
||||
00712023
|
||||
30200073
|
@@ -0,0 +1,22 @@
|
||||
010000b7
|
||||
02000137
|
||||
0000b1b7
|
||||
aaa18193
|
||||
00005237
|
||||
55520213
|
||||
00100313
|
||||
00100293
|
||||
30429073
|
||||
03400293
|
||||
00028293
|
||||
30529073
|
||||
00000063
|
||||
0000a383
|
||||
00338863
|
||||
00438a63
|
||||
00712023
|
||||
30200073
|
||||
00612223
|
||||
30200073
|
||||
02612223
|
||||
30200073
|
65
Labs/13. Peripheral units/firmware/software/ps2_hex.S
Normal file
65
Labs/13. Peripheral units/firmware/software/ps2_hex.S
Normal file
@@ -0,0 +1,65 @@
|
||||
_start:
|
||||
# Инициализируем начальные значения регистров
|
||||
0: 030000b7 li x1 , 0x03000000 # сохраняем базовый адрес клавиатуры
|
||||
4: 04000137 li x2 , 0x04000000 # сохраняем базовый адрес хекс-контроллера
|
||||
8: 0e000193 li x3 , 0x000000e0 # сохраняем сканкод e0
|
||||
c: 0f000213 li x4 , 0x000000f0 # сохраняем сканкод f0
|
||||
10: 00e00413 li x8 , 0x0000000e # сохраняем значение e
|
||||
14: 00f00493 li x9 , 0x0000000f # сохраняем значение f
|
||||
18: 00000593 li x11, 0x00000000 # сохраняем ноль
|
||||
1c: 00100293 li x5 , 0x00000001 # подготавливаем маску прерывания единственного
|
||||
# (нулевого) входа
|
||||
20: 30429073 csrw mie, x5 # загружаем маску в регистр маски
|
||||
24: 03400293 la x5, trap_handler # псевдоинструкция la аналогично li загружает число,
|
||||
28: 00028293 # только в случае la — это число является адресом
|
||||
# указанного места (адреса обработчика перехвата)
|
||||
# данная псевдоинструкция будет разбита на две
|
||||
# инструкции: lui и addi
|
||||
2c: 30529073 csrw mtvec, x5 # устанавливаем вектор прерывания
|
||||
|
||||
# Вызов функции main
|
||||
main:
|
||||
30: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1);
|
||||
|
||||
# ОБРАБОТЧИК ПЕРЕХВАТА
|
||||
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
|
||||
# однако в случае прерывания в программный счетчик будет загружен адрес первой
|
||||
# нижележащей инструкции.
|
||||
# Сохраняем используемые регистры на стек
|
||||
trap_handler:
|
||||
34: 0000a383 lw x7, 0(x1) # загружаем сканкод
|
||||
38: 04338263 beq x7, x3, print_e0 # если сканкод e0, отображаем с помощью print_e0
|
||||
3c: 04438c63 beq x7, x4, print_f0 # если сканкод f0, отображаем с помощью print_f0
|
||||
40: 00700333 add x6, x0, x7 # дублируем сканкод
|
||||
44: 00435313 srl x6, x6, 4 # сдвигаем на 4, чтобы получить старший нибл
|
||||
48: 00612223 sw x6, 4(x2) # записываем старший нибл в первый семисегментник
|
||||
4c: 00f3f393 andi x7, x7, 0xf # маскируем с f, чтобы получить младший нибл
|
||||
50: 00712023 sw x7, 0(x2) # записываем младший нибл в нулевой семисегментник
|
||||
54: 00b04c63 blt x0, x11, print_code # пропускаем обнуление старших хексов
|
||||
58: 00012a23 sw x0, 20(x2)
|
||||
5c: 00012823 sw x0, 16(x2) # обнуляем 2-5 семисегментники
|
||||
60: 00012623 sw x0, 12(x2)
|
||||
64: 00012423 sw x0, 8(x2)
|
||||
68: 00300513 addi x10, x0, 3
|
||||
|
||||
print_code:
|
||||
6c: 000005b3 add x11, x0, x0 # обнуляем счетчик
|
||||
70: 00356513 ori x10, x10, 3 # инициализируем маску, включающую 2 младших хекса
|
||||
74: 02a12023 sw x10, 32(x2) # записываем маску
|
||||
78: 30200073 mret # возвращаем управление программе (pc = mepc)
|
||||
# что означает возврат в бесконечный цикл
|
||||
print_e0:
|
||||
7c: 00812a23 sw x8, 20(x2) # записываем e в 5ый семисегментник
|
||||
80: 00012823 sw x0, 16(x2) # записываем 0 в 4ый семисегментник
|
||||
84: 03056513 ori x10, x10, 0x30 # включаем отображение 4-5 хексов в маске
|
||||
88: 02a12023 sw x10, 32(x2) # записываем маску
|
||||
8c: 00158593 addi x11, x11, 1 # инкрементируем счетчик
|
||||
90: 30200073 mret
|
||||
|
||||
print_f0:
|
||||
94: 00912623 sw x9, 12(x2) # записываем f в 3ый семисегментник
|
||||
98: 00012423 sw x0, 8(x2) # записываем 0 в 2ый семисегментник
|
||||
9c: 00c56513 ori x10, x10, 0xc # включаем отображение 3-2 хексов в маске
|
||||
a0: 02a12023 sw x10, 32(x2) # записываем маску
|
||||
a4: 00158593 addi x11, x11, 1 # инкрементируем счетчик
|
||||
a8: 30200073 mret
|
37
Labs/13. Peripheral units/firmware/software/ps2_vga.S
Normal file
37
Labs/13. Peripheral units/firmware/software/ps2_vga.S
Normal file
@@ -0,0 +1,37 @@
|
||||
_start:
|
||||
# Инициализируем начальные значения регистров
|
||||
0: 030000b7 li x1, 0x03000000 # сохраняем базовый адрес клавиатуры
|
||||
4: 07000137 li x2, 0x07000000 # сохраняем базовый адрес vga-контроллера
|
||||
8: 070011b7 li x3, 0x07000960 # количество символов на экране
|
||||
c: # данная псевдоинструкция будет разбита на две
|
||||
# инструкции: lui и addi
|
||||
10: 96018193 li x5, 0x00000001 # подготавливаем маску прерывания единственного
|
||||
# (нулевого) входа
|
||||
14: 00100293 csrw mie, x5 # загружаем маску в регистр маски
|
||||
18: 30429073 la x5, trap_handler # псевдоинструкция la аналогично li загружает число,
|
||||
# только в случае la — это число является адресом
|
||||
# указанного места (адреса обработчика перехвата)
|
||||
# данная псевдоинструкция будет разбита на две
|
||||
# инструкции: lui и addi
|
||||
1c: 30529073 csrw mtvec, x5 # устанавливаем вектор прерывания
|
||||
|
||||
# Вызов функции main
|
||||
main:
|
||||
20: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1);
|
||||
|
||||
# ОБРАБОТЧИК ПЕРЕХВАТА
|
||||
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
|
||||
# однако в случае прерывания в программный счетчик будет загружен адрес первой
|
||||
# нижележащей инструкции.
|
||||
# Сохраняем используемые регистры на стек
|
||||
trap_handler:
|
||||
24: 0000a383 lw x7, 0(x1) # загружаем сканкод
|
||||
28: 00038403 lb x8, 0(x7) # берем данные из таблицы подстановки
|
||||
2c: 00812023 sw x8, 0(x2) # загружаем ascii-значение в vga
|
||||
30: 00110113 addi x2, x2, 1 # инкрементируем адрес vga
|
||||
34: 00315463 bge x2, x3, wrap_addr # если адрес vga вышел за границы, то обнуляем
|
||||
38: 30200073 mret # возвращаем управление программе (pc = mepc)
|
||||
# что означает возврат в бесконечный цикл
|
||||
wrap_addr:
|
||||
3c: 07000137 li x2, 0x07000000 # сохраняем базовый адрес vga-контроллера
|
||||
40: 30200073 mret
|
34
Labs/13. Peripheral units/firmware/software/rx_hex.S
Normal file
34
Labs/13. Peripheral units/firmware/software/rx_hex.S
Normal file
@@ -0,0 +1,34 @@
|
||||
_start:
|
||||
# Инициализируем начальные значения регистров
|
||||
0: 050000b7 li x1 , 0x05000000 # сохраняем базовый адрес uart_rx
|
||||
4: 04000137 li x2 , 0x04000000 # сохраняем базовый адрес хекс-контроллера
|
||||
8: 0001c1b7 li x3 , 0x0001c200 # устанавливаем бодрейт 115200
|
||||
c: 20018193
|
||||
10: 0030a623 sw x3 , 0x0c(x1)
|
||||
14: 00100213 li x4 , 0x00000001 # устанавливаем parity_bit
|
||||
18: 0030a823 sw x4 , 0x10(x1)
|
||||
1c: 00100293 li x5 , 0x00000001 # подготавливаем маску прерывания единственного
|
||||
# (нулевого) входа
|
||||
20: 30429073 csrw mie, x5 # загружаем маску в регистр маски
|
||||
24: 03400293 la x5, trap_handler # псевдоинструкция la аналогично li загружает число,
|
||||
28: 00028293 # только в случае la — это число является адресом
|
||||
# указанного места (адреса обработчика перехвата)
|
||||
# данная псевдоинструкция будет разбита на две
|
||||
# инструкции: lui и addi
|
||||
2c: 30529073 csrw mtvec, x5 # устанавливаем вектор прерывания
|
||||
# Вызов функции main
|
||||
main:
|
||||
30: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1);
|
||||
# ОБРАБОТЧИК ПЕРЕХВАТА
|
||||
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
|
||||
# однако в случае прерывания в программный счетчик будет загружен адрес первой
|
||||
# нижележащей инструкции.
|
||||
# Сохраняем используемые регистры на стек
|
||||
trap_handler:
|
||||
34: 0000a383 lw x7, 0(x1) # загружаем пришедший байт
|
||||
38: 00700333 add x6, x0, x7 # дублируем сканкод
|
||||
3c: 00435313 srl x6, x6, 4 # сдвигаем на 4, чтобы получить старший нибл
|
||||
40: 00612223 sw x6, 4(x2) # записываем старший нибл в первый семисегментник
|
||||
44: 00f3f393 andi x7, x7, 0xf # маскируем с f, чтобы получить младший нибл
|
||||
48: 00712023 sw x7, 0(x2) # записываем младший нибл в нулевой семисегментник
|
||||
4c: 30200073 mret
|
50
Labs/13. Peripheral units/firmware/software/rx_led.S
Normal file
50
Labs/13. Peripheral units/firmware/software/rx_led.S
Normal file
@@ -0,0 +1,50 @@
|
||||
_start:
|
||||
# Инициализируем начальные значения регистров
|
||||
0: 050000b7 li x1, 0x05000000 # сохраняем базовый адрес uart_rx
|
||||
4: 02000137 li x2, 0x02000000 # сохраняем базовый адрес светодиодов
|
||||
8: 0001c1b7 li x3, 0x0001c200 # устанавливаем бодрейт 115200
|
||||
c: 20018193
|
||||
10: 0030a623 sw x3, 0x0c(x1)
|
||||
14: 00100213 li x4, 0x00000001 # устанавливаем parity_bit
|
||||
18: 0040a823 sw x4, 0x10(x1)
|
||||
1c: 000011b7 li x3, 0x00000D0D # сохраняем спец-код для режима моргания
|
||||
20: d0d18193
|
||||
24: 00008237 li x4, 0x00000808 # сохраняем спец-код для сброса
|
||||
28: f7f20213
|
||||
2c: 0ff00493 li x9, 0x000000ff # сохраняем маску для обнуления старшей части
|
||||
30: 00100313 li x6, 0x00000001 # сохраняем единицу
|
||||
34: 00100293 li x5, 0x00000001 # подготавливаем маску прерывания единственного
|
||||
# (нулевого) входа
|
||||
38: 30429073 csrw mie, x5 # загружаем маску в регистр маски
|
||||
|
||||
3c: 04c00293 la x5, trap_handler # псевдоинструкция la аналогично li загружает число,
|
||||
40: 00028293 # только в случае la — это число является адресом
|
||||
40: 00028293 # указанного места (адреса обработчика перехвата)
|
||||
# данная псевдоинструкция будет разбита на две
|
||||
# инструкции: lui и addi
|
||||
44: 30529073 csrw mtvec, x5 # устанавливаем вектор прерывания
|
||||
# Вызов функции main
|
||||
main:
|
||||
48: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1);
|
||||
# ОБРАБОТЧИК ПЕРЕХВАТА
|
||||
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
|
||||
# однако в случае прерывания в программный счетчик будет загружен адрес первой
|
||||
# нижележащей инструкции.
|
||||
# Сохраняем используемые регистры на стек
|
||||
trap_handler:
|
||||
4c: 0000a383 lw x7, 0(x1) # загружаем значение из uart rx
|
||||
50: 00947433 and x8, x8, x9 # обнуляем старые 3 байта
|
||||
54: 00841413 slli x8, x8, 8 # Сдвигаем регистр x8 на 1 байт влево
|
||||
58: 00746433 or x8, x8, x7 # записываем считанный из rx байт на освободившееся место
|
||||
5c: 00340863 beq x8, x3, blink_mode # если пришел спец-код моргания, переходим в blink_mode
|
||||
60: 00440a63 beq x8, x4, reset # если пришел спец-код сброса, переходим в reset
|
||||
64: 00812023 sw x8, 0(x2) # записываем значением с переключателей в светодиоды
|
||||
68: 30200073 mret # возвращаем управление программе (pc = mepc)
|
||||
# что означает возврат в бесконечный цикл
|
||||
blink_mode:
|
||||
6c: 00612223 sw x6, 4(x2) # записываем 1 в led_mode
|
||||
70: 30200073 mret
|
||||
|
||||
reset:
|
||||
74: 02612223 sw x6, 0x24(x2) # записываем 1 в led_reset
|
||||
78: 30200073 mret
|
32
Labs/13. Peripheral units/firmware/software/rx_tx.S
Normal file
32
Labs/13. Peripheral units/firmware/software/rx_tx.S
Normal file
@@ -0,0 +1,32 @@
|
||||
_start:
|
||||
# Инициализируем начальные значения регистров
|
||||
0: 050000b7 li x1 , 0x05000000 # сохраняем базовый адрес uart_rx
|
||||
4: 06000137 li x2 , 0x06000000 # сохраняем базовый адрес uart_tx
|
||||
8: 0001c1b7 li x3 , 0x0001c200 # устанавливаем бодрейт 115200
|
||||
c: 20018193
|
||||
10: 0030a623 sw x3 , 0x0c(x1)
|
||||
14: 00312623 sw x3 , 0x0c(x2)
|
||||
18: 00100213 li x4 , 0x00000001 # устанавливаем parity_bit
|
||||
1c: 0040a823 sw x4 , 0x10(x1)
|
||||
20: 00412823 sw x4 , 0x10(x2)
|
||||
24: 00100293 li x5 , 0x00000001 # подготавливаем маску прерывания единственного
|
||||
# (нулевого) входа
|
||||
28: 30429073 csrw mie, x5 # загружаем маску в регистр маски
|
||||
2c: 03c00293 la x5, trap_handler # псевдоинструкция la аналогично li загружает число,
|
||||
30: 00028293 # только в случае la — это число является адресом
|
||||
# указанного места (адреса обработчика перехвата)
|
||||
# данная псевдоинструкция будет разбита на две
|
||||
# инструкции: lui и addi
|
||||
34: 30529073 csrw mtvec, x5 # устанавливаем вектор прерывания
|
||||
# Вызов функции main
|
||||
main:
|
||||
38: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1);
|
||||
# ОБРАБОТЧИК ПЕРЕХВАТА
|
||||
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
|
||||
# однако в случае прерывания в программный счетчик будет загружен адрес первой
|
||||
# нижележащей инструкции.
|
||||
# Сохраняем используемые регистры на стек
|
||||
trap_handler:
|
||||
3c: 0000a383 lw x7, 0(x1) # загружаем пришедший байт
|
||||
40: 00712023 sw x7, 0(x2)
|
||||
44: 30200073 mret
|
40
Labs/13. Peripheral units/firmware/software/sw_led.S
Normal file
40
Labs/13. Peripheral units/firmware/software/sw_led.S
Normal file
@@ -0,0 +1,40 @@
|
||||
_start:
|
||||
# Инициализируем начальные значения регистров
|
||||
0: 010000b7 li x1, 0x01000000 # сохраняем базовый адрес переключателей
|
||||
4: 02000137 li x2, 0x02000000 # сохраняем базовый адрес светодиодов
|
||||
8: 0000b1b7 li x3, 0x0000aaaa # сохраняем спец-код для режима моргания
|
||||
c: aaa18193
|
||||
10: 00005237 li x4, 0x00005555 # сохраняем спец-код для сброса
|
||||
14: 55520213
|
||||
18: 00100313 li x6, 0x00000001 # сохраняем единицу
|
||||
1c: 00100293 li x5, 0x00000001 # подготавливаем маску прерывания единственного
|
||||
# (нулевого) входа
|
||||
20: 30429073 csrw mie, x5 # загружаем маску в регистр маски
|
||||
24: 03400293 la x5, trap_handler # псевдоинструкция la аналогично li загружает число,
|
||||
28: 00028293 # только в случае la — это число является адресом
|
||||
# указанного места (адреса обработчика перехвата)
|
||||
# данная псевдоинструкция будет разбита на две
|
||||
# инструкции: lui и addi
|
||||
2c: 30529073 csrw mtvec, x5 # устанавливаем вектор прерывания
|
||||
# Вызов функции main
|
||||
main:
|
||||
30: 00000063 beq x0, x0, main # бесконечный цикл, аналогичный while (1);
|
||||
# ОБРАБОТЧИК ПЕРЕХВАТА
|
||||
# Без стороннего вмешательства процессор никогда не перейдет к инструкциям ниже,
|
||||
# однако в случае прерывания в программный счетчик будет загружен адрес первой
|
||||
# нижележащей инструкции.
|
||||
# Сохраняем используемые регистры на стек
|
||||
trap_handler:
|
||||
34: 0000a383 lw x7, 0(x1) # загружаем значение на переключателях
|
||||
38: 00338863 beq x7, x3, blink_mode # если пришел спец-код моргания, переходим в blink_mode
|
||||
3c: 00438a63 beq x7, x4, reset # если пришел спец-код сброса, переходим в reset
|
||||
40: 00712023 sw x7, 0(x2) # записываем значением с переключателей в светодиоды
|
||||
44: 30200073 mret # возвращаем управление программе (pc = mepc)
|
||||
# что означает возврат в бесконечный цикл
|
||||
blink_mode:
|
||||
48: 00612223 sw x6, 4(x2) # записываем 1 в led_mode
|
||||
4c: 30200073 mret
|
||||
|
||||
reset:
|
||||
50: 02612223 sw x6, 0x24(x2) # записываем 1 в led_reset
|
||||
54: 30200073 mret
|
211
Labs/13. Peripheral units/nexys_a7_100t.xdc
Normal file
211
Labs/13. Peripheral units/nexys_a7_100t.xdc
Normal file
@@ -0,0 +1,211 @@
|
||||
## This file is a general .xdc for the Nexys A7-100T
|
||||
## To use it in a project:
|
||||
## - uncomment the lines corresponding to used pins
|
||||
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
|
||||
|
||||
# Clock signal
|
||||
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports clk_i]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk_i]
|
||||
create_generated_clock -name sys_clk10_pin -source [get_ports clk_i] -divide_by 10 [get_pins divider/clkbuf/O]
|
||||
|
||||
#Switches
|
||||
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports {sw_i[0]}]
|
||||
set_property -dict {PACKAGE_PIN L16 IOSTANDARD LVCMOS33} [get_ports {sw_i[1]}]
|
||||
set_property -dict {PACKAGE_PIN M13 IOSTANDARD LVCMOS33} [get_ports {sw_i[2]}]
|
||||
set_property -dict {PACKAGE_PIN R15 IOSTANDARD LVCMOS33} [get_ports {sw_i[3]}]
|
||||
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports {sw_i[4]}]
|
||||
set_property -dict {PACKAGE_PIN T18 IOSTANDARD LVCMOS33} [get_ports {sw_i[5]}]
|
||||
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports {sw_i[6]}]
|
||||
set_property -dict {PACKAGE_PIN R13 IOSTANDARD LVCMOS33} [get_ports {sw_i[7]}]
|
||||
set_property -dict {PACKAGE_PIN T8 IOSTANDARD LVCMOS18} [get_ports {sw_i[8]}]
|
||||
set_property -dict {PACKAGE_PIN U8 IOSTANDARD LVCMOS18} [get_ports {sw_i[9]}]
|
||||
set_property -dict {PACKAGE_PIN R16 IOSTANDARD LVCMOS33} [get_ports {sw_i[10]}]
|
||||
set_property -dict {PACKAGE_PIN T13 IOSTANDARD LVCMOS33} [get_ports {sw_i[11]}]
|
||||
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {sw_i[12]}]
|
||||
set_property -dict {PACKAGE_PIN U12 IOSTANDARD LVCMOS33} [get_ports {sw_i[13]}]
|
||||
set_property -dict {PACKAGE_PIN U11 IOSTANDARD LVCMOS33} [get_ports {sw_i[14]}]
|
||||
set_property -dict {PACKAGE_PIN V10 IOSTANDARD LVCMOS33} [get_ports {sw_i[15]}]
|
||||
|
||||
## LEDs
|
||||
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {led_o[0]}]
|
||||
set_property -dict {PACKAGE_PIN K15 IOSTANDARD LVCMOS33} [get_ports {led_o[1]}]
|
||||
set_property -dict {PACKAGE_PIN J13 IOSTANDARD LVCMOS33} [get_ports {led_o[2]}]
|
||||
set_property -dict {PACKAGE_PIN N14 IOSTANDARD LVCMOS33} [get_ports {led_o[3]}]
|
||||
set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS33} [get_ports {led_o[4]}]
|
||||
set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {led_o[5]}]
|
||||
set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVCMOS33} [get_ports {led_o[6]}]
|
||||
set_property -dict {PACKAGE_PIN U16 IOSTANDARD LVCMOS33} [get_ports {led_o[7]}]
|
||||
set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {led_o[8]}]
|
||||
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {led_o[9]}]
|
||||
set_property -dict {PACKAGE_PIN U14 IOSTANDARD LVCMOS33} [get_ports {led_o[10]}]
|
||||
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {led_o[11]}]
|
||||
set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports {led_o[12]}]
|
||||
set_property -dict {PACKAGE_PIN V14 IOSTANDARD LVCMOS33} [get_ports {led_o[13]}]
|
||||
set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVCMOS33} [get_ports {led_o[14]}]
|
||||
set_property -dict {PACKAGE_PIN V11 IOSTANDARD LVCMOS33} [get_ports {led_o[15]}]
|
||||
|
||||
### RGB LEDs
|
||||
#set_property -dict {PACKAGE_PIN R12 IOSTANDARD LVCMOS33} [get_ports LED16_B]
|
||||
#set_property -dict {PACKAGE_PIN M16 IOSTANDARD LVCMOS33} [get_ports LED16_G]
|
||||
#set_property -dict {PACKAGE_PIN N15 IOSTANDARD LVCMOS33} [get_ports LED16_R]
|
||||
#set_property -dict {PACKAGE_PIN G14 IOSTANDARD LVCMOS33} [get_ports LED17_B]
|
||||
#set_property -dict {PACKAGE_PIN R11 IOSTANDARD LVCMOS33} [get_ports LED17_G]
|
||||
#set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports LED17_R]
|
||||
|
||||
##7 segment display
|
||||
set_property -dict {PACKAGE_PIN T10 IOSTANDARD LVCMOS33} [get_ports hex_led_o[6]]
|
||||
set_property -dict {PACKAGE_PIN R10 IOSTANDARD LVCMOS33} [get_ports hex_led_o[5]]
|
||||
set_property -dict {PACKAGE_PIN K16 IOSTANDARD LVCMOS33} [get_ports hex_led_o[4]]
|
||||
set_property -dict {PACKAGE_PIN K13 IOSTANDARD LVCMOS33} [get_ports hex_led_o[3]]
|
||||
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports hex_led_o[2]]
|
||||
set_property -dict {PACKAGE_PIN T11 IOSTANDARD LVCMOS33} [get_ports hex_led_o[1]]
|
||||
set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports hex_led_o[0]]
|
||||
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
|
||||
set_property -dict {PACKAGE_PIN J17 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[0]}]
|
||||
set_property -dict {PACKAGE_PIN J18 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[1]}]
|
||||
set_property -dict {PACKAGE_PIN T9 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[2]}]
|
||||
set_property -dict {PACKAGE_PIN J14 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[3]}]
|
||||
set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[4]}]
|
||||
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[5]}]
|
||||
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[6]}]
|
||||
set_property -dict {PACKAGE_PIN U13 IOSTANDARD LVCMOS33} [get_ports {hex_sel_o[7]}]
|
||||
|
||||
##Buttons
|
||||
set_property -dict {PACKAGE_PIN C12 IOSTANDARD LVCMOS33} [get_ports resetn_i]
|
||||
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc
|
||||
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu
|
||||
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl
|
||||
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr
|
||||
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
|
||||
|
||||
|
||||
##Pmod Headers
|
||||
##Pmod Header JA
|
||||
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { JA[1] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
|
||||
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
|
||||
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { JA[3] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
|
||||
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { JA[4] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
|
||||
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7]
|
||||
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { JA[8] }]; #IO_L16P_T2_A28_15 Sch=ja[8]
|
||||
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { JA[9] }]; #IO_L22N_T3_A16_15 Sch=ja[9]
|
||||
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { JA[10] }]; #IO_L22P_T3_A17_15 Sch=ja[10]
|
||||
|
||||
##Pmod Header JB
|
||||
#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { JB[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1]
|
||||
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { JB[2] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2]
|
||||
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { JB[3] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3]
|
||||
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { JB[4] }]; #IO_L15P_T2_DQS_15 Sch=jb[4]
|
||||
#set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { JB[7] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7]
|
||||
#set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { JB[8] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8]
|
||||
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { JB[9] }]; #IO_0_15 Sch=jb[9]
|
||||
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { JB[10] }]; #IO_L13P_T2_MRCC_15 Sch=jb[10]
|
||||
|
||||
##Pmod Header JC
|
||||
#set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { JC[1] }]; #IO_L23N_T3_35 Sch=jc[1]
|
||||
#set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { JC[2] }]; #IO_L19N_T3_VREF_35 Sch=jc[2]
|
||||
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports { JC[3] }]; #IO_L22N_T3_35 Sch=jc[3]
|
||||
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { JC[4] }]; #IO_L19P_T3_35 Sch=jc[4]
|
||||
#set_property -dict { PACKAGE_PIN E7 IOSTANDARD LVCMOS33 } [get_ports { JC[7] }]; #IO_L6P_T0_35 Sch=jc[7]
|
||||
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports { JC[8] }]; #IO_L22P_T3_35 Sch=jc[8]
|
||||
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { JC[9] }]; #IO_L21P_T3_DQS_35 Sch=jc[9]
|
||||
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { JC[10] }]; #IO_L5P_T0_AD13P_35 Sch=jc[10]
|
||||
|
||||
##Pmod Header JD
|
||||
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { JD[1] }]; #IO_L21N_T3_DQS_35 Sch=jd[1]
|
||||
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports { JD[2] }]; #IO_L17P_T2_35 Sch=jd[2]
|
||||
#set_property -dict { PACKAGE_PIN G1 IOSTANDARD LVCMOS33 } [get_ports { JD[3] }]; #IO_L17N_T2_35 Sch=jd[3]
|
||||
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports { JD[4] }]; #IO_L20N_T3_35 Sch=jd[4]
|
||||
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports { JD[7] }]; #IO_L15P_T2_DQS_35 Sch=jd[7]
|
||||
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { JD[8] }]; #IO_L20P_T3_35 Sch=jd[8]
|
||||
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports { JD[9] }]; #IO_L15N_T2_DQS_35 Sch=jd[9]
|
||||
#set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { JD[10] }]; #IO_L13N_T2_MRCC_35 Sch=jd[10]
|
||||
|
||||
##Pmod Header JXADC
|
||||
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports { XA_N[1] }]; #IO_L9N_T1_DQS_AD3N_15 Sch=xa_n[1]
|
||||
#set_property -dict { PACKAGE_PIN A13 IOSTANDARD LVCMOS33 } [get_ports { XA_P[1] }]; #IO_L9P_T1_DQS_AD3P_15 Sch=xa_p[1]
|
||||
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports { XA_N[2] }]; #IO_L8N_T1_AD10N_15 Sch=xa_n[2]
|
||||
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { XA_P[2] }]; #IO_L8P_T1_AD10P_15 Sch=xa_p[2]
|
||||
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 } [get_ports { XA_N[3] }]; #IO_L7N_T1_AD2N_15 Sch=xa_n[3]
|
||||
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports { XA_P[3] }]; #IO_L7P_T1_AD2P_15 Sch=xa_p[3]
|
||||
#set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { XA_N[4] }]; #IO_L10N_T1_AD11N_15 Sch=xa_n[4]
|
||||
#set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { XA_P[4] }]; #IO_L10P_T1_AD11P_15 Sch=xa_p[4]
|
||||
|
||||
##VGA Connector
|
||||
set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { vga_r_o[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
|
||||
set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { vga_r_o[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
|
||||
set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { vga_r_o[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
|
||||
set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { vga_r_o[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
|
||||
set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { vga_g_o[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
|
||||
set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { vga_g_o[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
|
||||
set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { vga_g_o[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
|
||||
set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { vga_g_o[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
|
||||
set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { vga_b_o[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
|
||||
set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { vga_b_o[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
|
||||
set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { vga_b_o[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
|
||||
set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { vga_b_o[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
|
||||
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { vga_hs_o }]; #IO_L4P_T0_15 Sch=vga_hs
|
||||
set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { vga_vs_o }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
|
||||
|
||||
##Micro SD Connector
|
||||
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
|
||||
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
|
||||
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
|
||||
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }]; #IO_L16N_T2_35 Sch=sd_cmd
|
||||
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
|
||||
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
|
||||
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
|
||||
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
|
||||
|
||||
##Accelerometer
|
||||
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
|
||||
#set_property -dict { PACKAGE_PIN F14 IOSTANDARD LVCMOS33 } [get_ports { ACL_MOSI }]; #IO_L5N_T0_AD9N_15 Sch=acl_mosi
|
||||
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { ACL_SCLK }]; #IO_L14P_T2_SRCC_15 Sch=acl_sclk
|
||||
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { ACL_CSN }]; #IO_L12P_T1_MRCC_15 Sch=acl_csn
|
||||
#set_property -dict { PACKAGE_PIN B13 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[1] }]; #IO_L2P_T0_AD8P_15 Sch=acl_int[1]
|
||||
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { ACL_INT[2] }]; #IO_L20P_T3_A20_15 Sch=acl_int[2]
|
||||
|
||||
##Temperature Sensor
|
||||
#set_property -dict { PACKAGE_PIN C14 IOSTANDARD LVCMOS33 } [get_ports { TMP_SCL }]; #IO_L1N_T0_AD0N_15 Sch=tmp_scl
|
||||
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports { TMP_SDA }]; #IO_L12N_T1_MRCC_15 Sch=tmp_sda
|
||||
#set_property -dict { PACKAGE_PIN D13 IOSTANDARD LVCMOS33 } [get_ports { TMP_INT }]; #IO_L6N_T0_VREF_15 Sch=tmp_int
|
||||
#set_property -dict { PACKAGE_PIN B14 IOSTANDARD LVCMOS33 } [get_ports { TMP_CT }]; #IO_L2N_T0_AD8N_15 Sch=tmp_ct
|
||||
|
||||
##Omnidirectional Microphone
|
||||
#set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { M_CLK }]; #IO_25_35 Sch=m_clk
|
||||
#set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { M_DATA }]; #IO_L24N_T3_35 Sch=m_data
|
||||
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { M_LRSEL }]; #IO_0_35 Sch=m_lrsel
|
||||
|
||||
##PWM Audio Amplifier
|
||||
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { AUD_PWM }]; #IO_L4N_T0_15 Sch=aud_pwm
|
||||
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { AUD_SD }]; #IO_L6P_T0_15 Sch=aud_sd
|
||||
|
||||
##USB-RS232 Interface
|
||||
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { rx_i }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
|
||||
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { tx_o }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
|
||||
#set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
|
||||
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
|
||||
|
||||
##USB HID (PS/2)
|
||||
set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports kclk_i]
|
||||
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports kdata_i]
|
||||
|
||||
##SMSC Ethernet PHY
|
||||
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDC }]; #IO_L11P_T1_SRCC_16 Sch=eth_mdc
|
||||
#set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { ETH_MDIO }]; #IO_L14N_T2_SRCC_16 Sch=eth_mdio
|
||||
#set_property -dict { PACKAGE_PIN B3 IOSTANDARD LVCMOS33 } [get_ports { ETH_RSTN }]; #IO_L10P_T1_AD15P_35 Sch=eth_rstn
|
||||
#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { ETH_CRSDV }]; #IO_L6N_T0_VREF_16 Sch=eth_crsdv
|
||||
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXERR }]; #IO_L13N_T2_MRCC_16 Sch=eth_rxerr
|
||||
#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[0] }]; #IO_L13P_T2_MRCC_16 Sch=eth_rxd[0]
|
||||
#set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { ETH_RXD[1] }]; #IO_L19N_T3_VREF_16 Sch=eth_rxd[1]
|
||||
#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXEN }]; #IO_L11N_T1_SRCC_16 Sch=eth_txen
|
||||
#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[0] }]; #IO_L14P_T2_SRCC_16 Sch=eth_txd[0]
|
||||
#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { ETH_TXD[1] }]; #IO_L12N_T1_MRCC_16 Sch=eth_txd[1]
|
||||
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { ETH_REFCLK }]; #IO_L11P_T1_SRCC_35 Sch=eth_refclk
|
||||
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { ETH_INTN }]; #IO_L12P_T1_MRCC_16 Sch=eth_intn
|
||||
|
||||
##Quad SPI Flash
|
||||
#set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[0] }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0]
|
||||
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[1] }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1]
|
||||
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
|
||||
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
|
||||
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { QSPI_CSN }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
|
100
Labs/13. Peripheral units/peripheral modules/PS2Receiver.sv
Normal file
100
Labs/13. Peripheral units/peripheral modules/PS2Receiver.sv
Normal file
@@ -0,0 +1,100 @@
|
||||
module PS2Receiver(
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic kclk_i,
|
||||
input logic kdata_i,
|
||||
output logic [7:0] keycodeout_o,
|
||||
output keycode_valid_o
|
||||
);
|
||||
|
||||
logic flag;
|
||||
logic [3:0] flag_shift;
|
||||
logic kclkf, kdataf;
|
||||
logic [3:0] cnt;
|
||||
|
||||
assign keycode_valid_o = flag_shift[0] && !flag_shift[2];
|
||||
|
||||
debouncer debounce(
|
||||
.clk(clk_i),
|
||||
.I0(kclk_i),
|
||||
.I1(kdata_i),
|
||||
.O0(kclkf),
|
||||
.O1(kdataf)
|
||||
);
|
||||
always@(posedge clk_i) begin
|
||||
if(rst_i) begin
|
||||
flag_shift <= '0;
|
||||
end
|
||||
else begin
|
||||
flag_shift <= {flag_shift[2:0], flag};
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(negedge kclkf or posedge rst_i)begin
|
||||
if(rst_i) begin
|
||||
cnt <= '0;
|
||||
end
|
||||
else if (cnt <= 9) begin
|
||||
cnt <= cnt + 1;
|
||||
end
|
||||
else begin
|
||||
cnt <= '0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(negedge kclkf or posedge rst_i) begin
|
||||
if(rst_i) begin
|
||||
keycodeout_o <= '0;
|
||||
end
|
||||
else begin
|
||||
case(cnt)
|
||||
1:keycodeout_o[0]<=kdataf;
|
||||
2:keycodeout_o[1]<=kdataf;
|
||||
3:keycodeout_o[2]<=kdataf;
|
||||
4:keycodeout_o[3]<=kdataf;
|
||||
5:keycodeout_o[4]<=kdataf;
|
||||
6:keycodeout_o[5]<=kdataf;
|
||||
7:keycodeout_o[6]<=kdataf;
|
||||
8:keycodeout_o[7]<=kdataf;
|
||||
default: keycodeout_o <= keycodeout_o;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign flag = cnt == 9;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module debouncer(
|
||||
input logic clk,
|
||||
input logic I0,
|
||||
input logic I1,
|
||||
output logic O0,
|
||||
output logic O1
|
||||
);
|
||||
|
||||
logic [4:0]cnt0, cnt1;
|
||||
logic Iv0=0,Iv1=0;
|
||||
logic out0, out1;
|
||||
|
||||
always_ff @(posedge(clk))begin
|
||||
if (I0==Iv0) begin
|
||||
if (cnt0==19)O0<=I0;
|
||||
else cnt0<=cnt0+1;
|
||||
end
|
||||
else begin
|
||||
cnt0<=5'd0;
|
||||
Iv0<=I0;
|
||||
end
|
||||
if (I1==Iv1)begin
|
||||
if (cnt1==19)O1<=I1;
|
||||
else cnt1<=cnt1+1;
|
||||
end
|
||||
else begin
|
||||
cnt1<=5'd0;
|
||||
Iv1<=I1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
92
Labs/13. Peripheral units/peripheral modules/hex_digits.sv
Normal file
92
Labs/13. Peripheral units/peripheral modules/hex_digits.sv
Normal file
@@ -0,0 +1,92 @@
|
||||
module hex_digits(
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic [3:0] hex0_i, // Цифра, выводимой на нулевой (самый правый) индикатор
|
||||
input logic [3:0] hex1_i, // Цифра, выводимая на первый индикатор
|
||||
input logic [3:0] hex2_i, // Цифра, выводимая на второй индикатор
|
||||
input logic [3:0] hex3_i, // Цифра, выводимая на третий индикатор
|
||||
input logic [3:0] hex4_i, // Цифра, выводимая на четвертый индикатор
|
||||
input logic [3:0] hex5_i, // Цифра, выводимая на пятый индикатор
|
||||
input logic [3:0] hex6_i, // Цифра, выводимая на шестой индикатор
|
||||
input logic [3:0] hex7_i, // Цифра, выводимая на седьмой индикатор
|
||||
input logic [7:0] bitmask_i, // Битовая маска для включения/отключения
|
||||
// отдельных индикаторов
|
||||
|
||||
output logic [6:0] hex_led_o, // Сигнал, контролирующий каждый отдельный
|
||||
// светодиод индикатора
|
||||
output logic [7:0] hex_sel_o // Сигнал, указывающий на какой индикатор
|
||||
// выставляется hex_led
|
||||
);
|
||||
|
||||
logic [4:0] hex0, hex1, hex2, hex3, hex4, hex5, hex6, hex7;
|
||||
assign hex0 = {bitmask_i[0], hex0_i};
|
||||
assign hex1 = {bitmask_i[1], hex1_i};
|
||||
assign hex2 = {bitmask_i[2], hex2_i};
|
||||
assign hex3 = {bitmask_i[3], hex3_i};
|
||||
assign hex4 = {bitmask_i[4], hex4_i};
|
||||
assign hex5 = {bitmask_i[5], hex5_i};
|
||||
assign hex6 = {bitmask_i[6], hex6_i};
|
||||
assign hex7 = {bitmask_i[7], hex7_i};
|
||||
|
||||
localparam pwm = 32'd1000; //шим сегментов
|
||||
|
||||
logic [9:0] counter;
|
||||
logic [4:0] semseg;
|
||||
logic [7:0] ANreg;
|
||||
logic [6:0] hex_ledr;
|
||||
|
||||
assign hex_sel_o = ANreg;
|
||||
assign hex_led_o = hex_ledr;
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
if (rst_i) begin
|
||||
counter <= 'b0;
|
||||
ANreg[7:0] <= 8'b11111111;
|
||||
hex_ledr <= 7'b1111111;
|
||||
end
|
||||
else begin
|
||||
if (counter < pwm) counter <= counter + 'b1;
|
||||
else begin
|
||||
counter <= 'b0;
|
||||
ANreg[1] <= ANreg[0];
|
||||
ANreg[2] <= ANreg[1];
|
||||
ANreg[3] <= ANreg[2];
|
||||
ANreg[4] <= ANreg[3];
|
||||
ANreg[5] <= ANreg[4];
|
||||
ANreg[6] <= ANreg[5];
|
||||
ANreg[7] <= ANreg[6];
|
||||
ANreg[0] <= !(ANreg[6:0] == 7'b1111111);
|
||||
end
|
||||
case (1'b0)
|
||||
ANreg[0]: semseg <= hex0;
|
||||
ANreg[1]: semseg <= hex1;
|
||||
ANreg[2]: semseg <= hex2;
|
||||
ANreg[3]: semseg <= hex3;
|
||||
ANreg[4]: semseg <= hex4;
|
||||
ANreg[5]: semseg <= hex5;
|
||||
ANreg[6]: semseg <= hex6;
|
||||
ANreg[7]: semseg <= hex7;
|
||||
endcase
|
||||
case (semseg)
|
||||
5'h10: hex_ledr <= 7'b0000001;
|
||||
5'h11: hex_ledr <= 7'b1001111;
|
||||
5'h12: hex_ledr <= 7'b0010010;
|
||||
5'h13: hex_ledr <= 7'b0000110;
|
||||
5'h14: hex_ledr <= 7'b1001100;
|
||||
5'h15: hex_ledr <= 7'b0100100;
|
||||
5'h16: hex_ledr <= 7'b0100000;
|
||||
5'h17: hex_ledr <= 7'b0001111;
|
||||
5'h18: hex_ledr <= 7'b0000000;
|
||||
5'h19: hex_ledr <= 7'b0000100;
|
||||
5'h1A: hex_ledr <= 7'b0001000;
|
||||
5'h1B: hex_ledr <= 7'b1100000;
|
||||
5'h1C: hex_ledr <= 7'b0110001;
|
||||
5'h1D: hex_ledr <= 7'b1000010;
|
||||
5'h1E: hex_ledr <= 7'b0110000;
|
||||
5'h1F: hex_ledr <= 7'b0111000;
|
||||
default: hex_ledr <= 7'b1111111;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
279
Labs/13. Peripheral units/peripheral modules/uart_rx.sv
Normal file
279
Labs/13. Peripheral units/peripheral modules/uart_rx.sv
Normal file
@@ -0,0 +1,279 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
module uart_rx (
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
input logic rx_i,
|
||||
output logic busy_o,
|
||||
input logic [16:0] baudrate_i,
|
||||
input logic parity_en_i,
|
||||
input logic stopbit_i,
|
||||
output logic [7:0] rx_data_o,
|
||||
output logic rx_valid_o
|
||||
//, input logic cfg_en_i,
|
||||
// input logic [1:0] cfg_bits_i,
|
||||
// output logic err_o,
|
||||
// input logic err_clr_i,
|
||||
// input logic rx_ready_i
|
||||
);
|
||||
|
||||
logic rx_ready_i;
|
||||
logic cfg_en_i;
|
||||
logic [1:0] cfg_bits_i;
|
||||
logic rstn_i;
|
||||
logic [15:0] cfg_div_i;
|
||||
always_comb begin
|
||||
case(baudrate_i)
|
||||
17'd9600 : cfg_div_i = 15'd1041;
|
||||
17'd19200 : cfg_div_i = 15'd520;
|
||||
17'd38400 : cfg_div_i = 15'd259;
|
||||
17'd57600 : cfg_div_i = 15'd173;
|
||||
17'd115200: cfg_div_i = 15'd86;
|
||||
default : cfg_div_i = 15'd1041;
|
||||
endcase
|
||||
end
|
||||
assign rstn_i = !rst_i;
|
||||
assign rx_ready_i = 1'b1;
|
||||
assign cfg_en_i = 1'b1;
|
||||
assign cfg_bits_i = 2'd3;
|
||||
enum logic [2:0] {IDLE,START_BIT,DATA,SAVE_DATA,PARITY,STOP_BIT} CS, NS;
|
||||
|
||||
logic [7:0] reg_data;
|
||||
logic [7:0] reg_data_next;
|
||||
|
||||
logic [2:0] reg_rx_sync;
|
||||
|
||||
|
||||
logic [2:0] reg_bit_count;
|
||||
logic [2:0] reg_bit_count_next;
|
||||
|
||||
logic [2:0] s_target_bits;
|
||||
|
||||
logic parity_bit;
|
||||
logic parity_bit_next;
|
||||
|
||||
logic sampleData;
|
||||
|
||||
logic [15:0] baud_cnt;
|
||||
logic baudgen_en;
|
||||
logic bit_done;
|
||||
|
||||
logic start_bit;
|
||||
logic set_error;
|
||||
logic s_rx_fall;
|
||||
|
||||
|
||||
assign busy_o = (CS != IDLE);
|
||||
|
||||
always_comb
|
||||
begin
|
||||
case(cfg_bits_i)
|
||||
2'b00:
|
||||
s_target_bits = 3'h4;
|
||||
2'b01:
|
||||
s_target_bits = 3'h5;
|
||||
2'b10:
|
||||
s_target_bits = 3'h6;
|
||||
2'b11:
|
||||
s_target_bits = 3'h7;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin
|
||||
NS = CS;
|
||||
sampleData = 1'b0;
|
||||
reg_bit_count_next = reg_bit_count;
|
||||
reg_data_next = reg_data;
|
||||
rx_valid_o = 1'b0;
|
||||
baudgen_en = 1'b0;
|
||||
start_bit = 1'b0;
|
||||
parity_bit_next = parity_bit;
|
||||
set_error = 1'b0;
|
||||
|
||||
case(CS)
|
||||
IDLE:
|
||||
begin
|
||||
if (s_rx_fall)
|
||||
begin
|
||||
NS = START_BIT;
|
||||
baudgen_en = 1'b1;
|
||||
start_bit = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
START_BIT:
|
||||
begin
|
||||
parity_bit_next = 1'b0;
|
||||
baudgen_en = 1'b1;
|
||||
start_bit = 1'b1;
|
||||
if (bit_done)
|
||||
NS = DATA;
|
||||
end
|
||||
|
||||
DATA:
|
||||
begin
|
||||
baudgen_en = 1'b1;
|
||||
parity_bit_next = parity_bit ^ reg_rx_sync[2];
|
||||
case(cfg_bits_i)
|
||||
2'b00:
|
||||
reg_data_next = {3'b000,reg_rx_sync[2],reg_data[4:1]};
|
||||
2'b01:
|
||||
reg_data_next = {2'b00,reg_rx_sync[2],reg_data[5:1]};
|
||||
2'b10:
|
||||
reg_data_next = {1'b0,reg_rx_sync[2],reg_data[6:1]};
|
||||
2'b11:
|
||||
reg_data_next = {reg_rx_sync[2],reg_data[7:1]};
|
||||
endcase
|
||||
|
||||
if (bit_done)
|
||||
begin
|
||||
sampleData = 1'b1;
|
||||
if (reg_bit_count == s_target_bits)
|
||||
begin
|
||||
reg_bit_count_next = 'h0;
|
||||
NS = SAVE_DATA;
|
||||
end
|
||||
else
|
||||
begin
|
||||
reg_bit_count_next = reg_bit_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
SAVE_DATA:
|
||||
begin
|
||||
baudgen_en = 1'b1;
|
||||
rx_valid_o = 1'b1;
|
||||
if(rx_ready_i)
|
||||
if (parity_en_i)
|
||||
NS = PARITY;
|
||||
else
|
||||
NS = STOP_BIT;
|
||||
end
|
||||
PARITY:
|
||||
begin
|
||||
baudgen_en = 1'b1;
|
||||
if (bit_done)
|
||||
begin
|
||||
if(parity_bit != reg_rx_sync[2])
|
||||
set_error = 1'b1;
|
||||
NS = STOP_BIT;
|
||||
end
|
||||
end
|
||||
STOP_BIT:
|
||||
begin
|
||||
baudgen_en = 1'b1;
|
||||
if (bit_done)
|
||||
begin
|
||||
NS = IDLE;
|
||||
end
|
||||
end
|
||||
default:
|
||||
NS = IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rstn_i)
|
||||
begin
|
||||
if (rstn_i == 1'b0)
|
||||
begin
|
||||
CS <= IDLE;
|
||||
reg_data <= 8'hFF;
|
||||
reg_bit_count <= 'h0;
|
||||
parity_bit <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(bit_done)
|
||||
parity_bit <= parity_bit_next;
|
||||
if(sampleData)
|
||||
reg_data <= reg_data_next;
|
||||
|
||||
reg_bit_count <= reg_bit_count_next;
|
||||
if(cfg_en_i)
|
||||
CS <= NS;
|
||||
else
|
||||
CS <= IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
assign s_rx_fall = ~reg_rx_sync[1] & reg_rx_sync[2];
|
||||
always_ff @(posedge clk_i or negedge rstn_i)
|
||||
begin
|
||||
if (rstn_i == 1'b0)
|
||||
reg_rx_sync <= 3'b111;
|
||||
else
|
||||
begin
|
||||
if (cfg_en_i)
|
||||
reg_rx_sync <= {reg_rx_sync[1:0],rx_i};
|
||||
else
|
||||
reg_rx_sync <= 3'b111;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rstn_i)
|
||||
begin
|
||||
if (rstn_i == 1'b0)
|
||||
begin
|
||||
baud_cnt <= 'h0;
|
||||
bit_done <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(baudgen_en)
|
||||
begin
|
||||
if(!start_bit && (baud_cnt == cfg_div_i))
|
||||
begin
|
||||
baud_cnt <= 'h0;
|
||||
bit_done <= 1'b1;
|
||||
end
|
||||
else if(start_bit && (baud_cnt == {1'b0,cfg_div_i[15:1]}))
|
||||
begin
|
||||
baud_cnt <= 'h0;
|
||||
bit_done <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
baud_cnt <= baud_cnt + 1;
|
||||
bit_done <= 1'b0;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
baud_cnt <= 'h0;
|
||||
bit_done <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// always_ff @(posedge clk_i or negedge rstn_i)
|
||||
// begin
|
||||
// if (rstn_i == 1'b0)
|
||||
// begin
|
||||
// err_o <= 1'b0;
|
||||
// end
|
||||
// else
|
||||
// begin
|
||||
// if(err_clr_i)
|
||||
// begin
|
||||
// err_o <= 1'b0;
|
||||
// end
|
||||
// else
|
||||
// begin
|
||||
// if(set_error)
|
||||
// err_o <= 1'b1;
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
|
||||
assign rx_data_o = reg_data;
|
||||
|
||||
endmodule
|
233
Labs/13. Peripheral units/peripheral modules/uart_tx.sv
Normal file
233
Labs/13. Peripheral units/peripheral modules/uart_tx.sv
Normal file
@@ -0,0 +1,233 @@
|
||||
// Copyright 2017 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the “License”); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
module uart_tx (
|
||||
input logic clk_i,
|
||||
input logic rst_i,
|
||||
output logic tx_o,
|
||||
output logic busy_o,
|
||||
input logic [16:0] baudrate_i,
|
||||
input logic parity_en_i,
|
||||
input logic stopbit_i,
|
||||
input logic [7:0] tx_data_i,
|
||||
input logic tx_valid_i
|
||||
//, input logic cfg_en_i,
|
||||
// input logic [15:0] cfg_div_i,
|
||||
// input logic cfg_parity_en_i,
|
||||
// input logic [1:0] cfg_bits_i,
|
||||
// input logic stopbit_i,
|
||||
// output logic tx_ready_o
|
||||
);
|
||||
logic rstn_i;
|
||||
logic cfg_en_i;
|
||||
logic [1:0] cfg_bits_i;
|
||||
logic [15:0] cfg_div_i;
|
||||
logic tx_ready_o;
|
||||
assign rstn_i = !rst_i;
|
||||
assign cfg_en_i = 1'b1;
|
||||
assign cfg_bits_i = 2'd3;
|
||||
always_comb begin
|
||||
case(baudrate_i)
|
||||
17'd9600 : cfg_div_i = 15'd1041;
|
||||
17'd19200 : cfg_div_i = 15'd520;
|
||||
17'd38400 : cfg_div_i = 15'd259;
|
||||
17'd57600 : cfg_div_i = 15'd173;
|
||||
17'd115200: cfg_div_i = 15'd86;
|
||||
default : cfg_div_i = 15'd1041;
|
||||
endcase
|
||||
end
|
||||
enum logic [2:0] {IDLE,START_BIT,DATA,PARITY,STOP_BIT_FIRST,STOP_BIT_LAST} CS,NS;
|
||||
|
||||
logic [7:0] reg_data;
|
||||
logic [7:0] reg_data_next;
|
||||
|
||||
|
||||
logic [2:0] reg_bit_count;
|
||||
logic [2:0] reg_bit_count_next;
|
||||
|
||||
logic [2:0] s_target_bits;
|
||||
|
||||
logic parity_bit;
|
||||
logic parity_bit_next;
|
||||
|
||||
logic sampleData;
|
||||
|
||||
logic [15:0] baud_cnt;
|
||||
logic baudgen_en;
|
||||
logic bit_done;
|
||||
|
||||
assign busy_o = (CS != IDLE);
|
||||
|
||||
always_comb
|
||||
begin
|
||||
case(cfg_bits_i)
|
||||
2'b00:
|
||||
s_target_bits = 3'h4;
|
||||
2'b01:
|
||||
s_target_bits = 3'h5;
|
||||
2'b10:
|
||||
s_target_bits = 3'h6;
|
||||
2'b11:
|
||||
s_target_bits = 3'h7;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb
|
||||
begin
|
||||
NS = CS;
|
||||
tx_o = 1'b1;
|
||||
sampleData = 1'b0;
|
||||
reg_bit_count_next = reg_bit_count;
|
||||
reg_data_next = {1'b1,reg_data[7:1]};
|
||||
tx_ready_o = 1'b0;
|
||||
baudgen_en = 1'b0;
|
||||
parity_bit_next = parity_bit;
|
||||
case(CS)
|
||||
IDLE:
|
||||
begin
|
||||
if (cfg_en_i)
|
||||
tx_ready_o = 1'b1;
|
||||
if (tx_valid_i)
|
||||
begin
|
||||
NS = START_BIT;
|
||||
sampleData = 1'b1;
|
||||
reg_data_next = tx_data_i;
|
||||
end
|
||||
end
|
||||
|
||||
START_BIT:
|
||||
begin
|
||||
tx_o = 1'b0;
|
||||
parity_bit_next = 1'b0;
|
||||
baudgen_en = 1'b1;
|
||||
if (bit_done)
|
||||
NS = DATA;
|
||||
end
|
||||
|
||||
DATA:
|
||||
begin
|
||||
tx_o = reg_data[0];
|
||||
baudgen_en = 1'b1;
|
||||
parity_bit_next = parity_bit ^ reg_data[0];
|
||||
if (bit_done)
|
||||
begin
|
||||
if (reg_bit_count == s_target_bits)
|
||||
begin
|
||||
reg_bit_count_next = 'h0;
|
||||
if (parity_en_i)
|
||||
begin
|
||||
NS = PARITY;
|
||||
end
|
||||
else
|
||||
begin
|
||||
NS = STOP_BIT_FIRST;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
reg_bit_count_next = reg_bit_count + 1;
|
||||
sampleData = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
PARITY:
|
||||
begin
|
||||
tx_o = parity_bit;
|
||||
baudgen_en = 1'b1;
|
||||
if (bit_done)
|
||||
NS = STOP_BIT_FIRST;
|
||||
end
|
||||
STOP_BIT_FIRST:
|
||||
begin
|
||||
tx_o = 1'b1;
|
||||
baudgen_en = 1'b1;
|
||||
if (bit_done)
|
||||
begin
|
||||
if (stopbit_i)
|
||||
NS = STOP_BIT_LAST;
|
||||
else
|
||||
NS = IDLE;
|
||||
end
|
||||
end
|
||||
STOP_BIT_LAST:
|
||||
begin
|
||||
tx_o = 1'b1;
|
||||
baudgen_en = 1'b1;
|
||||
if (bit_done)
|
||||
begin
|
||||
NS = IDLE;
|
||||
end
|
||||
end
|
||||
default:
|
||||
NS = IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rstn_i)
|
||||
begin
|
||||
if (rstn_i == 1'b0)
|
||||
begin
|
||||
CS <= IDLE;
|
||||
reg_data <= 8'hFF;
|
||||
reg_bit_count <= 'h0;
|
||||
parity_bit <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(bit_done)
|
||||
begin
|
||||
parity_bit <= parity_bit_next;
|
||||
end
|
||||
|
||||
if(sampleData)
|
||||
begin
|
||||
reg_data <= reg_data_next;
|
||||
end
|
||||
|
||||
reg_bit_count <= reg_bit_count_next;
|
||||
if(cfg_en_i)
|
||||
CS <= NS;
|
||||
else
|
||||
CS <= IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rstn_i)
|
||||
begin
|
||||
if (rstn_i == 1'b0)
|
||||
begin
|
||||
baud_cnt <= 'h0;
|
||||
bit_done <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(baudgen_en)
|
||||
begin
|
||||
if(baud_cnt == cfg_div_i)
|
||||
begin
|
||||
baud_cnt <= 'h0;
|
||||
bit_done <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
baud_cnt <= baud_cnt + 1;
|
||||
bit_done <= 1'b0;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
baud_cnt <= 'h0;
|
||||
bit_done <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
614
Labs/13. Peripheral units/peripheral modules/vgachargen.sv
Normal file
614
Labs/13. Peripheral units/peripheral modules/vgachargen.sv
Normal file
@@ -0,0 +1,614 @@
|
||||
module vgachargen
|
||||
import vgachargen_pkg::*;
|
||||
#(
|
||||
parameter int unsigned CLK_FACTOR_25M = 100 / 25,
|
||||
parameter CH_T_RO_INIT_FILE_NAME = "lab12_vga_ch_t_ro.mem",
|
||||
parameter bit CH_T_RO_INIT_FILE_IS_BIN = 1,
|
||||
parameter CH_T_RW_INIT_FILE_NAME = "lab12_vga_ch_t_rw.mem",
|
||||
parameter bit CH_T_RW_INIT_FILE_IS_BIN = 1,
|
||||
parameter CH_MAP_INIT_FILE_NAME = "lab12_vga_ch_map.mem",
|
||||
parameter bit CH_MAP_INIT_FILE_IS_BIN = 0,
|
||||
parameter COL_MAP_INIT_FILE_NAME = "lab12_vga_col_map.mem",
|
||||
parameter bit COL_MAP_INIT_FILE_IS_BIN = 0
|
||||
) (
|
||||
input logic clk_i, // системный синхроимпульс
|
||||
input logic clk100m_i, // клок с частотой 100МГц
|
||||
input logic rst_i, // сигнал сброса
|
||||
|
||||
/*
|
||||
Интерфейс записи выводимого символа
|
||||
*/
|
||||
input logic [ 9:0] char_map_addr_i, // адрес позиции выводимого символа
|
||||
input logic char_map_we_i, // сигнал разрешения записи кода
|
||||
input logic [ 3:0] char_map_be_i, // сигнал выбора байтов для записи
|
||||
input logic [31:0] char_map_wdata_i, // ascii-код выводимого символа
|
||||
output logic [31:0] char_map_rdata_o, // сигнал чтения кода символа
|
||||
|
||||
/*
|
||||
Интерфейс установки цветовой схемы
|
||||
*/
|
||||
input logic [ 9:0] col_map_addr_i, // адрес позиции устанавливаемой схемы
|
||||
input logic col_map_we_i, // сигнал разрешения записи схемы
|
||||
input logic [ 3:0] col_map_be_i, // сигнал выбора байтов для записи
|
||||
input logic [31:0] col_map_wdata_i, // код устанавливаемой цветовой схемы
|
||||
output logic [31:0] col_map_rdata_o, // сигнал чтения кода схемы
|
||||
|
||||
/*
|
||||
Интерфейс установки шрифта.
|
||||
*/
|
||||
input logic [ 9:0] char_tiff_addr_i, // адрес позиции устанавливаемого шрифта
|
||||
input logic char_tiff_we_i, // сигнал разрешения записи шрифта
|
||||
input logic [ 3:0] char_tiff_be_i, // сигнал выбора байтов для записи
|
||||
input logic [31:0] char_tiff_wdata_i, // отображаемые пиксели в текущей позиции шрифта
|
||||
output logic [31:0] char_tiff_rdata_o, // сигнал чтения пикселей шрифта
|
||||
|
||||
output logic [3:0] vga_r_o, // красный канал vga
|
||||
output logic [3:0] vga_g_o, // зеленый канал vga
|
||||
output logic [3:0] vga_b_o, // синий канал vga
|
||||
output logic vga_hs_o, // линия горизонтальной синхронизации vga
|
||||
output logic vga_vs_o // линия вертикальной синхронизации vga
|
||||
);
|
||||
|
||||
logic [3:0] char_map_be_gated;
|
||||
assign char_map_be_gated = char_map_be_i & {4{char_map_we_i}};
|
||||
|
||||
logic [3:0] col_map_be_gated;
|
||||
assign col_map_be_gated = col_map_be_i & {4{col_map_we_i}};
|
||||
|
||||
logic arstn_i;
|
||||
assign arstn_i = ~rst_i;
|
||||
|
||||
logic [VGA_MAX_H_WIDTH-1:0] hcount_pixels;
|
||||
logic [VGA_MAX_V_WIDTH-1:0] vcount_pixels;
|
||||
|
||||
logic pixel_enable;
|
||||
logic pixel_enable_delayed;
|
||||
|
||||
delay #(
|
||||
.DATA_WIDTH (1),
|
||||
.DELAY_BY (2)
|
||||
) pixel_enable_delay (
|
||||
.clk_i (clk100m_i),
|
||||
.arstn_i (arstn_i),
|
||||
.data_i (pixel_enable),
|
||||
.data_o (pixel_enable_delayed)
|
||||
);
|
||||
|
||||
logic vga_vs_delayed;
|
||||
logic vga_vs;
|
||||
|
||||
delay #(
|
||||
.DATA_WIDTH (1),
|
||||
.DELAY_BY (2)
|
||||
) vga_vs_delay (
|
||||
.clk_i (clk100m_i),
|
||||
.arstn_i (arstn_i),
|
||||
.data_i (vga_vs),
|
||||
.data_o (vga_vs_delayed)
|
||||
);
|
||||
|
||||
logic vga_hs_delayed;
|
||||
logic vga_hs;
|
||||
|
||||
delay #(
|
||||
.DATA_WIDTH (1),
|
||||
.DELAY_BY (2)
|
||||
) vga_hs_delay (
|
||||
.clk_i (clk100m_i),
|
||||
.arstn_i (arstn_i),
|
||||
.data_i (vga_hs),
|
||||
.data_o (vga_hs_delayed)
|
||||
);
|
||||
|
||||
|
||||
vga_block #(
|
||||
.CLK_FACTOR_25M (CLK_FACTOR_25M)
|
||||
) vga_block (
|
||||
.clk_i (clk100m_i),
|
||||
.arstn_i (arstn_i),
|
||||
.hcount_o (hcount_pixels),
|
||||
.vcount_o (vcount_pixels),
|
||||
.pixel_enable_o (pixel_enable),
|
||||
.vga_hs_o (vga_hs),
|
||||
.vga_vs_o (vga_vs)
|
||||
);
|
||||
|
||||
logic [CH_MAP_ADDR_WIDTH-1:0] ch_map_addr_internal;
|
||||
|
||||
logic [BITMAP_ADDR_WIDTH-1:0] bitmap_addr;
|
||||
logic [BITMAP_ADDR_WIDTH-1:0] bitmap_addr_delayed;
|
||||
|
||||
delay #(
|
||||
.DATA_WIDTH (BITMAP_ADDR_WIDTH),
|
||||
.DELAY_BY (2)
|
||||
) bitmap_delay (
|
||||
.clk_i (clk100m_i),
|
||||
.arstn_i (arstn_i),
|
||||
.data_i (bitmap_addr),
|
||||
.data_o (bitmap_addr_delayed)
|
||||
);
|
||||
|
||||
index_generator index_generator (
|
||||
.vcount_i (vcount_pixels),
|
||||
.hcount_i (hcount_pixels),
|
||||
.ch_map_addr_o (ch_map_addr_internal),
|
||||
.bitmap_addr_o (bitmap_addr)
|
||||
);
|
||||
|
||||
|
||||
logic [CH_T_ADDR_WIDTH:0] ch_t_addr_internal;
|
||||
|
||||
logic [3:0][7:0] ch_map_data_word;
|
||||
|
||||
assign ch_t_addr_internal = ch_map_data_word[ch_map_addr_internal[1:0]];
|
||||
|
||||
true_dual_port_rw_bram #(
|
||||
.INIT_FILE_NAME (CH_MAP_INIT_FILE_NAME),
|
||||
.INIT_FILE_IS_BIN (CH_MAP_INIT_FILE_IS_BIN),
|
||||
.ADDR_WIDTH (10)
|
||||
) ch_map (
|
||||
.clka_i (clk_i),
|
||||
.clkb_i (clk100m_i),
|
||||
.addra_i (char_map_addr_i),
|
||||
.addrb_i (ch_map_addr_internal[$left(ch_map_addr_internal):2]),
|
||||
.wea_i (char_map_be_gated),
|
||||
.dina_i (char_map_wdata_i),
|
||||
.douta_o (char_map_rdata_o),
|
||||
.doutb_o (ch_map_data_word)
|
||||
);
|
||||
|
||||
logic [CH_T_ADDR_WIDTH-1:0] ch_t_ro_addr_internal;
|
||||
assign ch_t_ro_addr_internal = ch_t_addr_internal[CH_T_ADDR_WIDTH-1:0];
|
||||
logic [CH_T_DATA_WIDTH-1:0] ch_t_ro_data_internal;
|
||||
|
||||
single_port_ro_bram #(
|
||||
.INIT_FILE_NAME (CH_T_RO_INIT_FILE_NAME),
|
||||
.INIT_FILE_IS_BIN (CH_T_RO_INIT_FILE_IS_BIN),
|
||||
.DATA_WIDTH (CH_T_DATA_WIDTH),
|
||||
.ADDR_WIDTH (CH_T_ADDR_WIDTH)
|
||||
) ch_t_ro (
|
||||
.clk_i (clk100m_i),
|
||||
.addr_i(ch_t_ro_addr_internal),
|
||||
.dout_o(ch_t_ro_data_internal)
|
||||
);
|
||||
|
||||
logic [CH_T_ADDR_WIDTH-1:0] ch_t_rw_addr_internal;
|
||||
assign ch_t_rw_addr_internal = ch_t_ro_addr_internal;
|
||||
logic [CH_T_DATA_WIDTH-1:0] ch_t_rw_data_internal;
|
||||
|
||||
true_dual_port_rw_bram #(
|
||||
.INIT_FILE_NAME (CH_T_RW_INIT_FILE_NAME),
|
||||
.INIT_FILE_IS_BIN (CH_T_RW_INIT_FILE_IS_BIN),
|
||||
.NUM_COLS (1),
|
||||
.COL_WIDTH (CH_T_DATA_WIDTH),
|
||||
.ADDR_WIDTH (CH_T_ADDR_WIDTH)
|
||||
) ch_t_rw (
|
||||
.clka_i (clk_i),
|
||||
.clkb_i (clk100m_i),
|
||||
// .addra_i (ch_t_rw_addr_i),
|
||||
.addra_i (),
|
||||
.addrb_i (ch_t_rw_addr_internal),
|
||||
// .wea_i (ch_t_rw_wen_i),
|
||||
.wea_i (),
|
||||
// .dina_i (ch_t_rw_data_i),
|
||||
.dina_i (),
|
||||
// .douta_o (ch_t_rw_data_o),
|
||||
.douta_o (),
|
||||
.doutb_o (ch_t_rw_data_internal)
|
||||
);
|
||||
|
||||
logic [CH_T_DATA_WIDTH-1:0] ch_t_data_internal;
|
||||
assign ch_t_data_internal = ch_t_addr_internal[CH_T_ADDR_WIDTH] ? ch_t_rw_data_internal
|
||||
: ch_t_ro_data_internal;
|
||||
|
||||
logic [7:0] col_map_data_internal;
|
||||
logic [7:0] col_map_data_internal_delayed;
|
||||
|
||||
logic [3:0][7:0] col_map_data_internal_word;
|
||||
|
||||
assign col_map_data_internal = col_map_data_internal_word[ch_map_addr_internal[1:0]];
|
||||
|
||||
delay #(
|
||||
.DATA_WIDTH (8),
|
||||
.DELAY_BY (1)
|
||||
) col_map_data_delay (
|
||||
.clk_i (clk100m_i),
|
||||
.arstn_i (arstn_i),
|
||||
.data_i (col_map_data_internal),
|
||||
.data_o (col_map_data_internal_delayed)
|
||||
);
|
||||
|
||||
logic [3:0] fg_col_map_data;
|
||||
logic [3:0] bg_col_map_data;
|
||||
|
||||
assign fg_col_map_data = col_map_data_internal_delayed[7:4];
|
||||
assign bg_col_map_data = col_map_data_internal_delayed[3:0];
|
||||
|
||||
true_dual_port_rw_bram #(
|
||||
.INIT_FILE_NAME (COL_MAP_INIT_FILE_NAME),
|
||||
.INIT_FILE_IS_BIN (COL_MAP_INIT_FILE_IS_BIN),
|
||||
.ADDR_WIDTH (10)
|
||||
) col_map (
|
||||
.clka_i (clk_i),
|
||||
.clkb_i (clk100m_i),
|
||||
.addra_i (col_map_addr_i),
|
||||
.addrb_i (ch_map_addr_internal[$left(ch_map_addr_internal):2]),
|
||||
.wea_i (col_map_be_gated),
|
||||
.dina_i (col_map_wdata_i),
|
||||
.douta_o (col_map_rdata_o),
|
||||
.doutb_o (col_map_data_internal_word)
|
||||
);
|
||||
|
||||
logic currentPixel;
|
||||
assign currentPixel = ch_t_data_internal[bitmap_addr_delayed];
|
||||
|
||||
logic [11:0] fg_color;
|
||||
assign fg_color = color_decode(fg_col_map_data);
|
||||
|
||||
logic [11:0] bg_color;
|
||||
assign bg_color = color_decode(bg_col_map_data);
|
||||
|
||||
// register outputs
|
||||
logic [3:0] vga_r_ff;
|
||||
logic [3:0] vga_r_next;
|
||||
logic [3:0] vga_g_ff;
|
||||
logic [3:0] vga_g_next;
|
||||
logic [3:0] vga_b_ff;
|
||||
logic [3:0] vga_b_next;
|
||||
logic vga_vs_ff;
|
||||
logic vga_vs_next;
|
||||
logic vga_hs_ff;
|
||||
logic vga_hs_next;
|
||||
|
||||
assign vga_r_next = pixel_enable_delayed ? (currentPixel ? fg_color[11:8]: bg_color[11:8]) : '0;
|
||||
assign vga_g_next = pixel_enable_delayed ? (currentPixel ? fg_color[7:4] : bg_color[7:4]) : '0;
|
||||
assign vga_b_next = pixel_enable_delayed ? (currentPixel ? fg_color[3:0] : bg_color[3:0]) : '0;
|
||||
|
||||
assign vga_vs_next = vga_vs_delayed;
|
||||
assign vga_hs_next = vga_hs_delayed;
|
||||
|
||||
always_ff @(posedge clk100m_i or negedge arstn_i) begin
|
||||
if (!arstn_i) begin
|
||||
vga_r_ff <= '0;
|
||||
vga_g_ff <= '0;
|
||||
vga_b_ff <= '0;
|
||||
vga_hs_ff <= '0;
|
||||
vga_vs_ff <= '0;
|
||||
end else begin
|
||||
vga_r_ff <= vga_r_next;
|
||||
vga_g_ff <= vga_g_next;
|
||||
vga_b_ff <= vga_b_next;
|
||||
vga_hs_ff <= vga_hs_next;
|
||||
vga_vs_ff <= vga_vs_next;
|
||||
end
|
||||
end
|
||||
|
||||
assign vga_r_o = vga_r_ff;
|
||||
assign vga_g_o = vga_g_ff;
|
||||
assign vga_b_o = vga_b_ff;
|
||||
|
||||
assign vga_hs_o = vga_hs_ff;
|
||||
assign vga_vs_o = vga_vs_ff;
|
||||
|
||||
endmodule
|
||||
|
||||
module clk_divider # (
|
||||
parameter int unsigned DIVISOR = 2
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic arstn_i,
|
||||
output logic strb_o
|
||||
);
|
||||
localparam int unsigned COUNTER_WIDTH = (DIVISOR > 1) ? $clog2(DIVISOR) : 1;
|
||||
|
||||
logic [COUNTER_WIDTH-1:0] counter_next;
|
||||
logic [COUNTER_WIDTH-1:0] counter_ff;
|
||||
|
||||
assign counter_next = ~|counter_ff ? COUNTER_WIDTH'(DIVISOR - 1) : (counter_ff - COUNTER_WIDTH'(1));
|
||||
|
||||
always_ff @(posedge clk_i or negedge arstn_i) begin
|
||||
if (~arstn_i) counter_ff <= '0;
|
||||
else counter_ff <= counter_next;
|
||||
end
|
||||
|
||||
logic strb_ff;
|
||||
logic strb_next;
|
||||
|
||||
assign strb_next = ~|counter_ff;
|
||||
|
||||
always_ff @(posedge clk_i or negedge arstn_i) begin
|
||||
if (~arstn_i) strb_ff <= '0;
|
||||
else strb_ff <= strb_next;
|
||||
end
|
||||
|
||||
assign strb_o = strb_ff;
|
||||
|
||||
endmodule
|
||||
|
||||
module delay #(
|
||||
parameter int unsigned DATA_WIDTH = 8,
|
||||
parameter int unsigned DELAY_BY = 2
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic arstn_i,
|
||||
input logic [DATA_WIDTH-1:0] data_i,
|
||||
output logic [DATA_WIDTH-1:0] data_o
|
||||
);
|
||||
logic [DELAY_BY-1:0][DATA_WIDTH-1:0] data_ff ;
|
||||
logic [DELAY_BY-1:0][DATA_WIDTH-1:0] data_next;
|
||||
|
||||
if (DELAY_BY == 1) begin
|
||||
assign data_next = data_i;
|
||||
assign data_o = data_ff;
|
||||
end else begin
|
||||
assign data_next = {data_ff[DELAY_BY-2:0], data_i};
|
||||
assign data_o = data_ff[DELAY_BY-1];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge arstn_i) begin
|
||||
if (!arstn_i) data_ff <= '0;
|
||||
else data_ff <= data_next;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module index_generator
|
||||
import vgachargen_pkg::*;
|
||||
(
|
||||
input logic [VGA_MAX_V_WIDTH -1:0] vcount_i,
|
||||
input logic [VGA_MAX_H_WIDTH -1:0] hcount_i,
|
||||
|
||||
output logic [CH_MAP_ADDR_WIDTH-1:0] ch_map_addr_o,
|
||||
output logic [BITMAP_ADDR_WIDTH-1:0] bitmap_addr_o
|
||||
);
|
||||
|
||||
logic [CH_H_WIDTH-1:0] haddr_chars;
|
||||
logic [CH_V_WIDTH-1:0] vaddr_chars;
|
||||
|
||||
assign haddr_chars = CH_H_WIDTH'(hcount_i >> BITMAP_H_WIDTH);
|
||||
assign vaddr_chars = CH_V_WIDTH'(vcount_i >> BITMAP_V_WIDTH);
|
||||
|
||||
`define _MULT_BY_80(_x) ((_x << 6) + (_x << 4))
|
||||
assign ch_map_addr_o = `_MULT_BY_80(vaddr_chars) + haddr_chars;
|
||||
`undef _MULT_BY_80
|
||||
|
||||
logic [BITMAP_H_WIDTH-1:0] haddr_pixels;
|
||||
logic [BITMAP_V_WIDTH-1:0] vaddr_pixels;
|
||||
|
||||
assign haddr_pixels = hcount_i[BITMAP_H_WIDTH-1:0];
|
||||
assign vaddr_pixels = vcount_i[BITMAP_V_WIDTH-1:0];
|
||||
|
||||
`define _MULT_BY_8(_x) (_x << 3)
|
||||
assign bitmap_addr_o = `_MULT_BY_8(vaddr_pixels) + haddr_pixels;
|
||||
`undef _MULT_BY_8
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
module single_port_ro_bram #(
|
||||
parameter INIT_FILE_NAME = "",
|
||||
parameter INIT_FILE_IS_BIN = 0,
|
||||
parameter int unsigned DATA_WIDTH = 2,
|
||||
parameter int unsigned ADDR_WIDTH = 4,
|
||||
localparam int unsigned DEPTH_WORDS = 2 ** ADDR_WIDTH
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic [ADDR_WIDTH-1:0] addr_i,
|
||||
output logic [DATA_WIDTH-1:0] dout_o
|
||||
);
|
||||
logic [DATA_WIDTH-1:0] mem[DEPTH_WORDS];
|
||||
|
||||
if (INIT_FILE_IS_BIN) initial $readmemb(INIT_FILE_NAME, mem, 0, DEPTH_WORDS-1);
|
||||
else initial $readmemh(INIT_FILE_NAME, mem, 0, DEPTH_WORDS-1);
|
||||
|
||||
always_ff @(posedge clk_i) begin
|
||||
dout_o <= mem[addr_i];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module timing_generator
|
||||
import vgachargen_pkg::*;
|
||||
(
|
||||
input logic clk_i,
|
||||
input logic arstn_i,
|
||||
input logic en_i,
|
||||
|
||||
output logic vga_hs_o,
|
||||
output logic vga_vs_o,
|
||||
|
||||
// Display timing counters
|
||||
output logic [VGA_MAX_H_WIDTH-1:0] hcount_o,
|
||||
output logic [VGA_MAX_V_WIDTH-1:0] vcount_o,
|
||||
output logic pixel_enable_o
|
||||
|
||||
);
|
||||
|
||||
logic [VGA_MAX_H_WIDTH-1:0] hcount_ff;
|
||||
logic hcount_en;
|
||||
logic [VGA_MAX_H_WIDTH-1:0] hcount_next;
|
||||
|
||||
logic [VGA_MAX_V_WIDTH-1:0] vcount_ff;
|
||||
logic vcount_en;
|
||||
logic [VGA_MAX_V_WIDTH-1:0] vcount_next;
|
||||
|
||||
// Horizontal counter
|
||||
assign hcount_next = ( hcount_ff < ( HTOTAL - 1 ) ) ? ( hcount_ff + 1 ) : ( '0 );
|
||||
always_ff @ ( posedge clk_i or negedge arstn_i )
|
||||
if ( ~arstn_i ) hcount_ff <= '0;
|
||||
else if (en_i) hcount_ff <= hcount_next;
|
||||
|
||||
// Vertical counter
|
||||
assign vcount_en = ( hcount_ff == ( HTOTAL - 1 ) ) & en_i;
|
||||
assign vcount_next = ( vcount_ff < ( VTOTAL - 1 ) ) ? ( vcount_ff + 1 ) : ( '0 );
|
||||
always_ff @( posedge clk_i or negedge arstn_i )
|
||||
if ( ~arstn_i ) vcount_ff <= '0;
|
||||
else if ( vcount_en ) vcount_ff <= vcount_next;
|
||||
|
||||
enum {
|
||||
DISPLAY_S,
|
||||
FRONT_S,
|
||||
SYNC_S,
|
||||
BACK_S
|
||||
} hstate_ff, hstate_next,
|
||||
vstate_ff, vstate_next;
|
||||
|
||||
always_ff @( posedge clk_i or negedge arstn_i )
|
||||
if( ~arstn_i ) begin
|
||||
hstate_ff <= DISPLAY_S;
|
||||
vstate_ff <= DISPLAY_S;
|
||||
end else if (en_i) begin
|
||||
hstate_ff <= hstate_next;
|
||||
vstate_ff <= vstate_next;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
hstate_next = hstate_ff;
|
||||
unique case( hstate_ff)
|
||||
DISPLAY_S: if( hcount_ff == HD - 1 ) hstate_next = FRONT_S;
|
||||
|
||||
FRONT_S: if( hcount_ff == HD + HF - 1 ) hstate_next = SYNC_S;
|
||||
|
||||
SYNC_S: if( hcount_ff == HD + HF + HR - 1 ) hstate_next = BACK_S;
|
||||
|
||||
BACK_S: if( hcount_ff == HTOTAL - 1 ) hstate_next = DISPLAY_S;
|
||||
|
||||
default: hstate_next = DISPLAY_S;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
vstate_next = vstate_ff;
|
||||
if( vcount_en ) begin
|
||||
unique case( vstate_ff)
|
||||
DISPLAY_S: if( vcount_ff == VD - 1 ) vstate_next = FRONT_S;
|
||||
|
||||
FRONT_S: if( vcount_ff == VD + VF - 1 ) vstate_next = SYNC_S;
|
||||
|
||||
SYNC_S: if( vcount_ff == VD + VF + VR - 1 ) vstate_next = BACK_S;
|
||||
|
||||
BACK_S: if( vcount_ff == VTOTAL - 1 ) vstate_next = DISPLAY_S;
|
||||
|
||||
default: vstate_next = DISPLAY_S;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
logic vga_vs_ff;
|
||||
logic vga_vs_next;
|
||||
|
||||
assign vga_vs_next = vstate_next inside {DISPLAY_S, FRONT_S, BACK_S};
|
||||
|
||||
always_ff @(posedge clk_i or negedge arstn_i) begin
|
||||
if (!arstn_i) vga_vs_ff <= 1'b1;
|
||||
else if (en_i) vga_vs_ff <= vga_vs_next;
|
||||
end
|
||||
|
||||
logic vga_hs_ff;
|
||||
logic vga_hs_next;
|
||||
|
||||
assign vga_hs_next = hstate_next inside {DISPLAY_S, FRONT_S, BACK_S};
|
||||
|
||||
always_ff @(posedge clk_i or negedge arstn_i) begin
|
||||
if (!arstn_i) vga_hs_ff <= 1'b1;
|
||||
else if (en_i) vga_hs_ff <= vga_hs_next;
|
||||
end
|
||||
|
||||
logic pixel_enable_ff;
|
||||
logic pixel_enable_next;
|
||||
|
||||
assign pixel_enable_next = ( vstate_next == DISPLAY_S ) && ( hstate_next == DISPLAY_S );
|
||||
|
||||
always_ff @(posedge clk_i or negedge arstn_i) begin
|
||||
if (!arstn_i) pixel_enable_ff <= 1'b0;
|
||||
else if (en_i) pixel_enable_ff <= pixel_enable_next;
|
||||
end
|
||||
|
||||
assign vga_hs_o = vga_hs_ff;
|
||||
assign vga_vs_o = vga_vs_ff;
|
||||
|
||||
assign pixel_enable_o = pixel_enable_ff;
|
||||
|
||||
assign hcount_o = hcount_ff;
|
||||
assign vcount_o = vcount_ff;
|
||||
endmodule
|
||||
|
||||
module true_dual_port_rw_bram #(
|
||||
parameter INIT_FILE_NAME = "",
|
||||
parameter INIT_FILE_IS_BIN = 0,
|
||||
parameter int unsigned COL_WIDTH = 8,
|
||||
parameter int unsigned NUM_COLS = 4,
|
||||
parameter int unsigned ADDR_WIDTH = 4,
|
||||
localparam int unsigned DATA_WIDTH = NUM_COLS * COL_WIDTH,
|
||||
localparam int unsigned DEPTH_WORDS = 2 ** ADDR_WIDTH
|
||||
) (
|
||||
input logic clka_i,
|
||||
input logic clkb_i,
|
||||
input logic [ADDR_WIDTH-1:0] addra_i,
|
||||
input logic [ADDR_WIDTH-1:0] addrb_i,
|
||||
input logic [NUM_COLS -1:0] wea_i,
|
||||
input logic [DATA_WIDTH-1:0] dina_i,
|
||||
output logic [DATA_WIDTH-1:0] douta_o,
|
||||
output logic [DATA_WIDTH-1:0] doutb_o
|
||||
);
|
||||
logic [DATA_WIDTH-1:0] mem[DEPTH_WORDS];
|
||||
|
||||
if (INIT_FILE_NAME != "") begin : use_init_file
|
||||
if (INIT_FILE_IS_BIN) initial $readmemb(INIT_FILE_NAME, mem, 0, DEPTH_WORDS-1);
|
||||
else initial $readmemh(INIT_FILE_NAME, mem, 0, DEPTH_WORDS-1);
|
||||
end else begin : init_bram_to_zero
|
||||
initial begin
|
||||
for (int unsigned i = 0; i < DEPTH_WORDS; ++i) mem[i] = '0;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clka_i) begin
|
||||
for (int i = 0; i < NUM_COLS; ++i) begin
|
||||
if (wea_i[i]) mem[addra_i][i*COL_WIDTH+:COL_WIDTH] <= dina_i[i*COL_WIDTH+:COL_WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clka_i) begin
|
||||
douta_o <= mem[addra_i];
|
||||
end
|
||||
|
||||
always_ff @(posedge clkb_i) begin
|
||||
doutb_o <= mem[addrb_i];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module vga_block
|
||||
import vgachargen_pkg::*;
|
||||
#(
|
||||
parameter int unsigned CLK_FACTOR_25M = 4
|
||||
) (
|
||||
input logic clk_i,
|
||||
input logic arstn_i,
|
||||
output logic [VGA_MAX_H_WIDTH-1:0] hcount_o,
|
||||
output logic [VGA_MAX_V_WIDTH-1:0] vcount_o,
|
||||
output logic pixel_enable_o,
|
||||
output logic vga_hs_o,
|
||||
output logic vga_vs_o
|
||||
);
|
||||
logic clk_divider_strb;
|
||||
|
||||
clk_divider # (
|
||||
.DIVISOR (CLK_FACTOR_25M)
|
||||
) clk_divider (
|
||||
.clk_i,
|
||||
.arstn_i,
|
||||
.strb_o (clk_divider_strb)
|
||||
);
|
||||
|
||||
timing_generator timing_generator (
|
||||
.clk_i,
|
||||
.arstn_i,
|
||||
.en_i (clk_divider_strb),
|
||||
.vga_hs_o,
|
||||
.vga_vs_o,
|
||||
.hcount_o,
|
||||
.vcount_o,
|
||||
.pixel_enable_o
|
||||
|
||||
);
|
||||
endmodule
|
@@ -0,0 +1,78 @@
|
||||
package vgachargen_pkg;
|
||||
|
||||
parameter int unsigned HD = 640; // Display area
|
||||
parameter int unsigned HF = 16; // Front porch
|
||||
parameter int unsigned HR = 96; // Retrace/Sync
|
||||
parameter int unsigned HB = 48; // Back Porch
|
||||
parameter int unsigned VD = 480;
|
||||
parameter int unsigned VF = 10;
|
||||
parameter int unsigned VR = 2;
|
||||
parameter int unsigned VB = 33;
|
||||
|
||||
parameter int unsigned HTOTAL = HD + HF + HR + HB;
|
||||
parameter int unsigned VTOTAL = VD + VF + VR + VB;
|
||||
|
||||
parameter int unsigned VGA_MAX_H_WIDTH = $clog2(HTOTAL);
|
||||
parameter int unsigned VGA_MAX_V_WIDTH = $clog2(VTOTAL);
|
||||
|
||||
parameter int unsigned BITMAP_H_PIXELS = 8;
|
||||
parameter int unsigned BITMAP_V_PIXELS = 16;
|
||||
parameter int unsigned BITMAP_H_WIDTH = $clog2(BITMAP_H_PIXELS);
|
||||
parameter int unsigned BITMAP_V_WIDTH = $clog2(BITMAP_V_PIXELS);
|
||||
parameter int unsigned CH_T_DATA_WIDTH = BITMAP_H_PIXELS * BITMAP_V_PIXELS;
|
||||
parameter int unsigned BITMAP_ADDR_WIDTH = $clog2(CH_T_DATA_WIDTH);
|
||||
parameter int unsigned CHARSET_COUNT = 256;
|
||||
parameter int unsigned CH_T_ADDR_WIDTH = $clog2(CHARSET_COUNT/2);
|
||||
|
||||
parameter int unsigned CH_H_PIXELS = HD / BITMAP_H_PIXELS;
|
||||
parameter int unsigned CH_V_PIXELS = VD / BITMAP_V_PIXELS;
|
||||
parameter int unsigned CH_V_WIDTH = $clog2(CH_V_PIXELS);
|
||||
parameter int unsigned CH_H_WIDTH = $clog2(CH_H_PIXELS);
|
||||
parameter int unsigned CH_MAP_ADDR_WIDTH = CH_V_WIDTH + CH_H_WIDTH;
|
||||
parameter int unsigned CH_MAP_DATA_WIDTH = CH_T_ADDR_WIDTH + 1;
|
||||
parameter int unsigned COL_MAP_ADDR_WIDTH = CH_MAP_ADDR_WIDTH;
|
||||
|
||||
typedef enum logic [23:0] {
|
||||
COL_0 = 24'h000000,
|
||||
COL_1 = 24'h0000d8,
|
||||
COL_2 = 24'h00d800,
|
||||
COL_3 = 24'h00d8d8,
|
||||
COL_4 = 24'hd80000,
|
||||
COL_5 = 24'hd800d8,
|
||||
COL_6 = 24'hd8d800,
|
||||
COL_7 = 24'hd8d8d8,
|
||||
COL_9 = 24'h0000ff,
|
||||
COL_10 = 24'h00ff00,
|
||||
COL_11 = 24'h00ffff,
|
||||
COL_12 = 24'hff0000,
|
||||
COL_13 = 24'hff00ff,
|
||||
COL_14 = 24'hffff00,
|
||||
COL_15 = 24'hffffff
|
||||
} rgb_t;
|
||||
|
||||
function automatic logic [11:0] rgb2half(rgb_t rgb_i);
|
||||
return {rgb_i[23:20], rgb_i[15:12], rgb_i[7:4]};
|
||||
endfunction
|
||||
|
||||
function automatic logic [11:0] color_decode(logic [3:0] color_encoded_i);
|
||||
unique case (color_encoded_i)
|
||||
4'h0 : return rgb2half(COL_0 );
|
||||
4'h1 : return rgb2half(COL_1 );
|
||||
4'h2 : return rgb2half(COL_2 );
|
||||
4'h3 : return rgb2half(COL_3 );
|
||||
4'h4 : return rgb2half(COL_4 );
|
||||
4'h5 : return rgb2half(COL_5 );
|
||||
4'h6 : return rgb2half(COL_6 );
|
||||
4'h7 : return rgb2half(COL_7 );
|
||||
4'h8 : return rgb2half(COL_0 );
|
||||
4'h9 : return rgb2half(COL_9 );
|
||||
4'ha : return rgb2half(COL_10);
|
||||
4'hb : return rgb2half(COL_11);
|
||||
4'hc : return rgb2half(COL_12);
|
||||
4'hd : return rgb2half(COL_13);
|
||||
4'he : return rgb2half(COL_14);
|
||||
4'hf : return rgb2half(COL_15);
|
||||
default: return rgb2half(COL_0 );
|
||||
endcase
|
||||
endfunction
|
||||
endpackage
|
54
Labs/13. Peripheral units/sys_clk_rst_gen.sv
Normal file
54
Labs/13. Peripheral units/sys_clk_rst_gen.sv
Normal file
@@ -0,0 +1,54 @@
|
||||
module sys_clk_rst_gen#(
|
||||
parameter DIV_WIDTH = 4
|
||||
)(
|
||||
input logic ex_clk_i,
|
||||
input logic ex_areset_n_i,
|
||||
input logic [DIV_WIDTH-1:0] div_i,
|
||||
|
||||
output logic sys_clk_o,
|
||||
output logic sys_reset_o
|
||||
);
|
||||
|
||||
logic [1:0] ex_arstn_buf;
|
||||
logic [DIV_WIDTH-1:0] sys_rstn_buf;
|
||||
|
||||
logic ex_arstn_buffered;
|
||||
assign ex_arstn_buffered = ex_arstn_buf[1];
|
||||
assign sys_reset_o = !sys_rstn_buf[DIV_WIDTH-1];
|
||||
|
||||
always_ff @(posedge ex_clk_i or negedge ex_areset_n_i) begin
|
||||
if(!ex_areset_n_i) begin
|
||||
ex_arstn_buf <= 2'b0;
|
||||
end
|
||||
else begin
|
||||
ex_arstn_buf <= {ex_arstn_buf[0], 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
logic [DIV_WIDTH-1:0] cnt;
|
||||
logic clk_div;
|
||||
always_ff @(posedge ex_clk_i or negedge ex_arstn_buffered) begin
|
||||
if ( ~ex_arstn_buffered ) begin
|
||||
cnt <= 0;
|
||||
clk_div <= 0;
|
||||
end else if ( cnt == 0 ) begin
|
||||
cnt <= div_i-1;
|
||||
clk_div <= !clk_div;
|
||||
end else begin
|
||||
cnt <= cnt - 1;
|
||||
end
|
||||
end
|
||||
|
||||
BUFG clkbuf (.O(sys_clk_o),.I(clk_div));
|
||||
|
||||
always_ff @(posedge sys_clk_o or negedge ex_arstn_buffered) begin
|
||||
if(!ex_arstn_buffered) begin
|
||||
sys_rstn_buf <= 2'b0;
|
||||
end
|
||||
else begin
|
||||
sys_rstn_buf <= {sys_rstn_buf[DIV_WIDTH-2:0], 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
125
Labs/13. Peripheral units/tb_riscv_unit.sv
Normal file
125
Labs/13. Peripheral units/tb_riscv_unit.sv
Normal file
@@ -0,0 +1,125 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company: MIET
|
||||
// Engineer: Andrei Solodovnikov
|
||||
|
||||
// Module Name: tb_riscv_unit
|
||||
// Project Name: RISCV_practicum
|
||||
// Target Devices: Nexys A7-100T
|
||||
// Description: tb for peripheral units
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module tb_riscv_unit();
|
||||
|
||||
logic clk;
|
||||
logic ps2_clk;
|
||||
logic ps2_dat;
|
||||
logic resetn;
|
||||
logic [15:0] sw_i;
|
||||
logic [15:0] led_o;
|
||||
logic parity;
|
||||
logic starter;
|
||||
|
||||
logic [ 6:0] hex_led_o;
|
||||
logic [ 7:0] hex_sel_o;
|
||||
logic rx_i;
|
||||
logic tx_o;
|
||||
|
||||
logic [3:0] cntr;
|
||||
|
||||
initial begin clk = 0; ps2_clk = 0; end
|
||||
|
||||
always #5ns clk = ~clk;
|
||||
always #50000 if(starter || (cntr > 0)) ps2_clk = ~ps2_clk; else ps2_clk = 1;
|
||||
|
||||
logic [11:0] data, uart_data;
|
||||
|
||||
initial #6ms $finish();
|
||||
|
||||
initial begin
|
||||
resetn = 1;
|
||||
repeat(20)@(posedge clk);
|
||||
resetn = 0;
|
||||
repeat(20) @(posedge clk);
|
||||
resetn = 1;
|
||||
end
|
||||
|
||||
riscv_unit dut(
|
||||
.clk_i (clk ),
|
||||
.resetn_i (resetn ),
|
||||
.sw_i (sw_i ),
|
||||
.led_o (led_o ),
|
||||
.kclk_i (ps2_clk ),
|
||||
.kdata_i (ps2_dat ),
|
||||
.hex_led_o(hex_led_o),
|
||||
.hex_sel_o(hex_sel_o),
|
||||
.rx_i (rx_i ),
|
||||
.tx_o (tx_o )
|
||||
);
|
||||
|
||||
initial begin: sw_block
|
||||
sw_i = 16'd0;
|
||||
repeat(1000) @(posedge clk);
|
||||
sw_i = 16'hdead;
|
||||
repeat(1000) @(posedge clk);
|
||||
sw_i = 16'h5555;
|
||||
repeat(1000) @(posedge clk);
|
||||
sw_i = 16'hbeef;
|
||||
repeat(1000) @(posedge clk);
|
||||
sw_i = 16'haaaa;
|
||||
end
|
||||
|
||||
|
||||
always @(negedge ps2_clk) begin: ps2_always_block
|
||||
if(starter || (cntr > 0))
|
||||
if(cntr == 10)
|
||||
cntr <= 0;
|
||||
else
|
||||
cntr <= cntr + 1;
|
||||
end
|
||||
|
||||
assign ps2_dat = cntr>0? data[cntr-1] : 1;
|
||||
|
||||
initial begin: ps2_initial_block
|
||||
cntr = 0;
|
||||
starter = 0;
|
||||
data = 0;
|
||||
repeat(10000) @(posedge clk);
|
||||
ps2_send_scan_code(8'h1c);
|
||||
ps2_send_scan_code(8'he0);
|
||||
ps2_send_scan_code(8'hf0);
|
||||
ps2_send_scan_code(8'h1c);
|
||||
ps2_send_scan_code(8'h5c);
|
||||
end
|
||||
|
||||
task ps2_send_scan_code(input logic [7:0] code);
|
||||
data = {2'b11, !(^code), code, 1'b0};
|
||||
starter = 1;
|
||||
@(posedge ps2_clk);
|
||||
starter = 0;
|
||||
repeat(10) @(posedge ps2_clk);
|
||||
endtask
|
||||
|
||||
|
||||
initial begin: uart_rx_initial_block
|
||||
uart_data = '1;
|
||||
repeat(1000) @(posedge clk);
|
||||
uart_rx_send_char(8'h1c, 115200);
|
||||
uart_rx_send_char(8'h0D, 115200);
|
||||
uart_rx_send_char(8'h0D, 115200);
|
||||
uart_rx_send_char(8'h7F, 115200);
|
||||
uart_rx_send_char(8'h7F, 115200);
|
||||
end
|
||||
assign rx_i = uart_data[0];
|
||||
int uart_cntr;
|
||||
task uart_rx_send_char(input logic [7:0] char, input logic [31:0] baudrate);
|
||||
uart_data = {2'b11, (^char), char, 1'b0};
|
||||
uart_cntr = 0;
|
||||
while(uart_cntr <= 15) begin
|
||||
#(1s/baudrate);
|
||||
uart_data = {1'b1, uart_data[11:1]};
|
||||
uart_cntr++;
|
||||
end
|
||||
endtask
|
||||
|
||||
endmodule
|
Reference in New Issue
Block a user