mirror of
https://github.com/MPSU/APS.git
synced 2025-09-16 01:30:10 +00:00
Обновление структуры лаб
This commit is contained in:
95
Labs/12. Peripheral units/PS2Receiver.v
Normal file
95
Labs/12. Peripheral units/PS2Receiver.v
Normal file
@@ -0,0 +1,95 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module PS2Receiver(
|
||||
input clk,
|
||||
input kclk,
|
||||
input kdata,
|
||||
output reg [15:0] keycodeout,
|
||||
output keycode_valid
|
||||
);
|
||||
|
||||
reg flag;
|
||||
reg [3:0] flag_shift;
|
||||
wire kclkf, kdataf;
|
||||
reg [3:0]cnt;
|
||||
|
||||
assign keycode_valid = flag_shift[0] && !flag_shift[2];
|
||||
|
||||
initial begin //for tb
|
||||
cnt = 0;
|
||||
keycodeout = 0;
|
||||
flag_shift = 0;
|
||||
flag = 0;
|
||||
end
|
||||
|
||||
debouncer debounce(
|
||||
.clk(clk),
|
||||
.I0(kclk),
|
||||
.I1(kdata),
|
||||
.O0(kclkf),
|
||||
.O1(kdataf)
|
||||
);
|
||||
always@(posedge clk) begin
|
||||
flag_shift <= (flag_shift << 1) + flag;
|
||||
end
|
||||
|
||||
always@(negedge(kclkf))begin
|
||||
case(cnt)
|
||||
0:if(keycodeout != 16'hE000)keycodeout <= 0;//Start bit
|
||||
1:keycodeout[0]<=kdataf;
|
||||
2:keycodeout[1]<=kdataf;
|
||||
3:keycodeout[2]<=kdataf;
|
||||
4:keycodeout[3]<=kdataf;
|
||||
5:keycodeout[4]<=kdataf;
|
||||
6:keycodeout[5]<=kdataf;
|
||||
7:keycodeout[6]<=kdataf;
|
||||
8:keycodeout[7]<=kdataf;
|
||||
//TODO ADD PARITY CHECK
|
||||
9:begin
|
||||
flag<=1'b1;
|
||||
if(keycodeout[7:0] == 8'hE0) begin
|
||||
keycodeout <= {keycodeout[7:0], 8'd0};
|
||||
end
|
||||
end
|
||||
10:flag<=1'b0;
|
||||
default: cnt <= 0;
|
||||
endcase
|
||||
if(cnt<=9) cnt<=cnt+1;
|
||||
else if(cnt==10) cnt<=0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module debouncer(
|
||||
input clk,
|
||||
input I0,
|
||||
input I1,
|
||||
output reg O0,
|
||||
output reg O1
|
||||
);
|
||||
|
||||
reg [4:0]cnt0, cnt1;
|
||||
reg Iv0=0,Iv1=0;
|
||||
reg out0, out1;
|
||||
|
||||
always@(posedge(clk))begin
|
||||
if (I0==Iv0)begin
|
||||
if (cnt0==19)O0<=I0;
|
||||
else cnt0<=cnt0+1;
|
||||
end
|
||||
else begin
|
||||
cnt0<="00000";
|
||||
Iv0<=I0;
|
||||
end
|
||||
if (I1==Iv1)begin
|
||||
if (cnt1==19)O1<=I1;
|
||||
else cnt1<=cnt1+1;
|
||||
end
|
||||
else begin
|
||||
cnt1<="00000";
|
||||
Iv1<=I1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
570
Labs/12. Peripheral units/README.md
Normal file
570
Labs/12. Peripheral units/README.md
Normal file
@@ -0,0 +1,570 @@
|
||||
# Лабораторная работа 7 "Периферийные устройства"
|
||||
|
||||
На прошлой лабораторной работе вы реализовали свой собственный RISC-V процессор. Однако пока что он находится "в вакууме" и никак не связан с внешним миром. Для исправления этого недостатка вами будет реализована системная шина, через которую к процессору смогут подключаться различные периферийные устройства.
|
||||
|
||||
## Цель
|
||||
|
||||
Интегрировать периферийные устройства в процессорную систему.
|
||||
|
||||
---
|
||||
|
||||
## Допуск к лабораторной работе
|
||||
|
||||
Для успешного выполнения лабораторной работы, вам необходимо:
|
||||
|
||||
* ознакомиться с [примером описания модуля-контроллера](../../Basic%20Verilog%20structures/Controllers.md);
|
||||
* ознакомиться с [описанием](#описание-контроллеров-периферийных-устройств) контроллеров периферийных устройств.
|
||||
|
||||
## Ход работы
|
||||
|
||||
1. Изучить теорию об адресном пространстве
|
||||
2. Получить индивидуальный вариант со своим набором периферийных устройств
|
||||
3. Интегрировать контроллеры периферийных устройств в адресное пространство вашей системы
|
||||
4. Собрать финальную схему вашей системы
|
||||
5. Проверить работу системы в ПЛИС с помощью демонстрационного ПО, загружаемого в память инструкций
|
||||
|
||||
---
|
||||
|
||||
## Теория
|
||||
|
||||
Помимо процессора и памяти, третьим ключевым элементом вычислительной системы является система ввода/вывода, обеспечивающая обмен информации между ядром вычислительной машины и периферийными устройствами.
|
||||
|
||||
Любое периферийное устройство, со стороны вычислительной машины, представляется набором ячеек памяти (регистров). С помощью чтения и записи этих регистров происходит обмен информации с периферийным устройством, и управление им. Например, датчик температуры может быть реализован самыми разными способами, но для процессора он в любом случае ячейка памяти, из которой он считывает число – температуру.
|
||||
|
||||
Система ввода/вывода может быть организована одним из двух способов: с **выделенным адресным пространством** устройств ввода/вывода, или с **совместным адресным пространством**. В первом случае система ввода/вывода имеет отдельную шину для подключения к процессору (и отдельные инструкции для обращения к периферии), во втором – шина для памяти и системы ввода/вывода общая (а обращение к периферии осуществляется теми же инструкциями, что и обращение к памяти).
|
||||
|
||||
### Адресное пространство
|
||||
|
||||
Архитектура RISC-V подразумевает использование совместного адресного пространства, это значит, что в лабораторной работе будет использована единая шина для подключения памяти и регистров управления периферийными устройствами. При обращении по одному диапазону адресов процессор будет
|
||||
попадать в память, при обращении по другим – взаимодействовать с регистрами управления/статуса периферийного устройства. Например, можно разделить 32-битное адресное пространство на 256 частей, отдав старшие 8 бит адреса под указание конкретного периферийного устройства. Тогда каждое из периферийных устройств получит 24-битное адресное пространство (16 MiB). Допустим, мы распределили эти части адресного пространства в следующем порядке (от младшего диапазона адресов к старшему):
|
||||
|
||||
0. Переключатели
|
||||
1. Светодиоды
|
||||
2. Клавиатура PS/2
|
||||
3. Семисегментные индикаторы
|
||||
4. UART-приемник
|
||||
5. UART-передатчик
|
||||
|
||||
В таком случае, если мы захотим обратиться в четвертый регистр семисегментных индикаторов, мы должны будем использовать адрес `0x03000004`. Старшие 8 бит (`0x03`) определяют выбранное периферийное устройство, оставшиеся 24 бита определяют конкретный адрес в адресном пространстве этого устройства.
|
||||
|
||||
На рисунке ниже представлен способ подключения процессора к памяти инструкций и данных, а так же 255 периферийным устройствам.
|
||||
|
||||

|
||||
|
||||
### Активация выбранного устройства
|
||||
|
||||
В зависимости от интерфейса используемой шины, периферийные устройства либо знают какой диапазон адресов им выделен (например, в интерфейсе I²C), либо нет (интерфейс APB). В первом случае, устройство понимает что к нему обратились непосредственно по адресу в данном обращении, во втором случае — по специальному сигналу.
|
||||
|
||||
На приведенной выше схеме используется второй вариант — устройство понимает, что к нему обратились по специальному сигналу `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
|
||||
);
|
||||
//...
|
||||
endmodule
|
||||
```
|
||||
|
||||
Эти входы порты подключены к одноименным портам ваших контроллеров периферии (речь идет только о реализуемых вами контроллерах, остальные порты должны остаться неподключенными).
|
||||
|
||||
Обратите внимание на то, что изменился сигнал сброса (`resetn_i`). Буква `n` на конце означает, что сброс работает по уровню `0` (когда сигнал равен нулю — это сброс, когда единице — не сброс).
|
||||
|
||||
Помимо прочего, необходимо подключить к вашему модулю `блок делителя частоты`. Поскольку в данном курсе лабораторных работ вы выполняли реализацию однотактного процессора, инструкция должна пройти через все ваши блоки за один такт. Из-за этого критический путь вашей схемы не позволит использовать тактовый сигнал частотой в `100 МГц`, от которого работает отладочный стенд. Поэтому, необходимо создать отдельный сигнал с пониженной тактовой частотой, от которого будет работать ваша схема.
|
||||
|
||||
Для этого необходимо:
|
||||
|
||||
1. Подключить файл [`sys_clk_rst_gen.v`](sys_clk_rst_gen.v) в ваш проект.
|
||||
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(10),.sys_clk_o(sysclk), .sys_reset_o(rst));
|
||||
```
|
||||
|
||||
3. После вставки данных строк в начало описания модуля `riscv_unit` вы получите тактовый сигнал `sysclk` с частотой в 10 МГц и сигнал сброса `rst` с активным уровнем `1` (как и в предыдущих лабораторных). Все ваши внутренние модули (`riscv_core`, `data_mem` и `контроллеры периферии`) должны работать от тактового сигнала `sysclk`. На модули, имеющие входной сигнал сброса (`rst_i`) необходимо подать ваш сигнал `rst`.
|
||||
|
||||
---
|
||||
|
||||
## Задание
|
||||
|
||||
В рамках данной лабораторной работы необходимо реализовать модули-контроллеры двух периферийных устройств, реализующих управление в соответствии с приведенной ниже картой памяти и встроить их в процессорную систему, используя используя схему приведенную выше. На карте приведено шесть периферийных устройств, вам необходимо взять только два из них в зависимости от вашего варианта индивидуального задания (ИЗ) по следующему правилу:
|
||||
|
||||
1. Те кому достались варианты ИЗ 1-5 должны реализовать контроллеры переключателей и светодиодов.
|
||||
2. Те кому достались варианты ИЗ 6-15 должны реализовать контроллеры клавиатуры PS/2 и семисегментных индикаторов.
|
||||
3. Те кому достались варианты BP 16-29 должны реализовать контроллеры приемника и передатчика UART.
|
||||
|
||||

|
||||
|
||||
Работа с картой осуществляется следующим образом. Под названием каждого периферийного устройства указана старшая часть адреса (чему должны быть равны старшие 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).
|
||||
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. Интегрируйте модули контроллеров периферии в процессорную систему по приведенной схеме руководствуясь старшими адресами контроллеров, представленными на карте памяти. Это означает, что если вы реализуете контроллер светодиодов, на его входов `req_i` должна подаваться единица в случае если `mem_req_o == 1` и старшие 8 бит адреса равны `0x02`.
|
||||
1. При интеграции вы должны подключить только модули-контроллеры вашего варианта. Контроллеры периферии других вариантов подключать не надо.
|
||||
2. При этом во время интеграции, вы должны использовать старшую часть адреса, представленную в карте памяти для формирования сигнала `req_i` для ваших модулей-контроллеров.
|
||||
3. Даже если вы не используете какие-то входные/выходные сигналы в модуле `riscv_unit` (например по варианту вам не достался контроллер клавиатуры и поэтому вы не используете сигналы `kclk_i` и `kdata_i`), вы все равно должны их описать во входах и выходах модуля `riscv_unit`.
|
||||
6. Проинициализируйте память инструкций с помощью предоставленной для каждой пары контроллеров программы.
|
||||
7. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе.
|
||||
8. Проверьте работу вашей процессорной системы с помощью отладочного стенда с ПЛИС и (при соответствующем варианте) клавиатуры/рабочего компьютера.
|
||||
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` должно подаваться значение `32'hfa11_1eaf`. Это никак не повлияет на работу процессора, но будет удобно в процессе отладки на временной диаграмме (тоже самое было сделано в процессе разработки памяти данных).
|
||||
|
||||
Если пришел **запрос на запись** или **чтение**, это еще не значит, что контроллер должен его выполнить. В случае, если запрос происходит по адресу, не поддерживающему этот запрос (например **запрос на запись** по адресу поддерживающему только чтение или наоборот), данный запрос должен игнорироваться, а на выходе `read_data_o` должно появиться значение `32'hdead_beef`.
|
||||
|
||||
К примеру, в случае запроса на чтение по адресу `0x0100004` (четвертый байт в адресном пространстве периферийного устройства "переключатели"), на выходе `read_data_o` должно оказаться значение `32'hdead_beef`. В случае отсутствия запроса на чтение (`req_i == 0` или `write_enable_i == 1`), на выходе `read_data_o` контроллера переключателей должно оказаться значение `32'hfa11_1eaf`.
|
||||
|
||||
В случае осуществления записи по принятому запросу, необходимо записать данные с сигнала `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,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к периферии
|
||||
*/
|
||||
input logic [15:0] sw_i
|
||||
);
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
По сути, логика работы контроллера сводится к тому, выдавать на шину `read_data_o` данные со входа `sw_i` каждый раз, когда приходит **запрос на чтение** по нулевому адресу. Поскольку разрядность `sw_i` в два раза меньше разрядности выхода `read_data_o` его старшие биты необходимо дополнить нулями.
|
||||
|
||||
Адресное пространство контроллера:
|
||||
|
||||
|Адрес|Режим доступа| Функциональное назначение |
|
||||
|-----|-------------|-------------------------------------------------|
|
||||
|0x00 | R | Чтение значения, выставленного на переключателях|
|
||||
|
||||
### Светодиоды
|
||||
|
||||
Как и переключатели, светодиоды являются простейшим устройством вывода. Поэтому, чтобы задание было интересней, для их управления был добавлен регистр, управляющий режимом вывода данных на светодиоды.
|
||||
Рассмотрим прототип модуля, который вам необходимо реализовать:
|
||||
|
||||
```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` должна игнорироваться.
|
||||
|
||||
Отсчет времени можно реализовать простейшим счетчиком, каждый такт увеличивающимся на 1 и сбрасывающимся по достижении определенного значения, чтобы продолжить считать с нуля. Зная тактовую частоту, нетрудно определить до скольки должен считать счетчик. При тактовой частоте в 10 МГц происходит 10 миллионов тактов в секунду. Это означает, что при такой тактовой частоте через секунду счетчик будет равен `10⁷-1` (счет идет с нуля).
|
||||
|
||||
Обратите внимание на то, что адрес `0x24` является адресом сброса. В случае записи по этому адресу единицы вы должны сбросить регистры `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 [15: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,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение к модулю,
|
||||
осуществляющему прием данных с клавиатуры
|
||||
*/
|
||||
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` необходимо обнулить.
|
||||
|
||||
В случае запроса на чтение по адресу `0x04` необходимо вернуть значение регистра `scan_code_is_unread`.
|
||||
|
||||
В случае запроса на запись по адресу `0x24` со значением `1`, необходимо осуществить сброс регистров `scan_code` и `scan_code_is_unread` в `0`.
|
||||
|
||||
Адресное пространство контроллера:
|
||||
|
||||
|Адрес|Режим доступа|Допустимые значения| Функциональное назначение |
|
||||
|-----|-------------|-------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
|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:31] | Регистр, хранящий значение, выводимое на hex0 |
|
||||
|0x04 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex1 |
|
||||
|0x08 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex2 |
|
||||
|0x0C | RW | [0:31] | Регистр, хранящий значение, выводимое на hex3 |
|
||||
|0x10 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex4 |
|
||||
|0x14 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex5 |
|
||||
|0x18 | RW | [0:31] | Регистр, хранящий значение, выводимое на hex6 |
|
||||
|0x1C | RW | [0:31] | Регистр, хранящий значение, выводимое на 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 [15: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 [15: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,
|
||||
|
||||
/*
|
||||
Часть интерфейса модуля, отвечающая за подключение передающему,
|
||||
входные данные по UART
|
||||
*/
|
||||
input logic rx_i
|
||||
);
|
||||
|
||||
logic busy;
|
||||
logic [15:0] baudrate;
|
||||
logic parity_en;
|
||||
logic stopbit;
|
||||
logic 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 [15:0] baudrate;
|
||||
logic parity_en;
|
||||
logic stopbit;
|
||||
|
||||
endmodule
|
||||
```
|
||||
|
||||
У обоих предоставленных модулей схожий прототип, различия заключаются лишь в направлениях некоторых сигналов:
|
||||
|
||||
Управление сигналами этого модуля достаточно просто.
|
||||
|
||||
Сигналы `clk_i` и `rx_i`/`tx_i` подключаются напрямую к соответствующим сигналам модуля-контроллера.
|
||||
|
||||
Сигнал `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`. Сам регистр доступен для чтения по адресу `0x04`.
|
||||
|
||||
На вход `tx_data_i` модуля `uart_tx` подаются данные из регистра `data` модуля `uart_tx_sb_ctrl`. Доступ на запись в этот регистр происходит по адресу `0x00` в моменты положительного фронта `clk_i`, когда сигнал `busy_o` равен нулю. Доступ на чтение этого регистра может осуществляться в любой момент времени.
|
||||
|
||||
На вход `tx_valid_i` модуля `uart_tx` подается единица в момент выполнения запроса на запись по адресу `0x00` (при сигнале `busy` равном нулю). В остальное время на вход этого сигнала подается `0`.
|
||||
|
||||
В случае запроса на запись единицы по адресу `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 | Запись сигнала сброса |
|
78
Labs/12. Peripheral units/hex_digits.v
Normal file
78
Labs/12. Peripheral units/hex_digits.v
Normal file
@@ -0,0 +1,78 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module hex_digits(
|
||||
input clk_i, rst_i,
|
||||
input [4:0] hex0, // Входной сигнал со значением цифры, выводимой на нулевой (самый правый) индикатор
|
||||
input [4:0] hex1, // Входной сигнал со значением цифры, выводимой на первый индикатор
|
||||
input [4:0] hex2, // Входной сигнал со значением цифры, выводимой на второй индикатор
|
||||
input [4:0] hex3, // Входной сигнал со значением цифры, выводимой на третий индикатор
|
||||
input [4:0] hex4, // Входной сигнал со значением цифры, выводимой на четвертый индикатор
|
||||
input [4:0] hex5, // Входной сигнал со значением цифры, выводимой на пятый индикатор
|
||||
input [4:0] hex6, // Входной сигнал со значением цифры, выводимой на шестой индикатор
|
||||
input [4:0] hex7, // Входной сигнал со значением цифры, выводимой на седьмой индикатор
|
||||
|
||||
output [6:0] hex_led, // Выходной сигнал, контролирующий каждый отдельный светодиод индикатора
|
||||
output [7:0] hex_sel // Выходной сигнал, указывающий на какой индикатор выставляется hex_led
|
||||
);
|
||||
`define pwm 1000 //шим сегментов
|
||||
|
||||
reg [9:0] counter;
|
||||
reg [4:0] semseg;
|
||||
reg [7:0] ANreg;
|
||||
reg [6:0] hex_ledr;
|
||||
|
||||
assign hex_sel = ANreg;
|
||||
assign hex_led = hex_ledr;
|
||||
|
||||
always @(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
|
211
Labs/12. Peripheral units/nexys_a7_100t.xdc
Normal file
211
Labs/12. 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 div/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[6]]
|
||||
set_property -dict {PACKAGE_PIN R10 IOSTANDARD LVCMOS33} [get_ports hex_led[5]]
|
||||
set_property -dict {PACKAGE_PIN K16 IOSTANDARD LVCMOS33} [get_ports hex_led[4]]
|
||||
set_property -dict {PACKAGE_PIN K13 IOSTANDARD LVCMOS33} [get_ports hex_led[3]]
|
||||
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports hex_led[2]]
|
||||
set_property -dict {PACKAGE_PIN T11 IOSTANDARD LVCMOS33} [get_ports hex_led[1]]
|
||||
set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports hex_led[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[0]}]
|
||||
set_property -dict {PACKAGE_PIN J18 IOSTANDARD LVCMOS33} [get_ports {hex_sel[1]}]
|
||||
set_property -dict {PACKAGE_PIN T9 IOSTANDARD LVCMOS33} [get_ports {hex_sel[2]}]
|
||||
set_property -dict {PACKAGE_PIN J14 IOSTANDARD LVCMOS33} [get_ports {hex_sel[3]}]
|
||||
set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports {hex_sel[4]}]
|
||||
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {hex_sel[5]}]
|
||||
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {hex_sel[6]}]
|
||||
set_property -dict {PACKAGE_PIN U13 IOSTANDARD LVCMOS33} [get_ports {hex_sel[7]}]
|
||||
|
||||
##Buttons
|
||||
set_property -dict {PACKAGE_PIN C12 IOSTANDARD LVCMOS33} [get_ports resetn]
|
||||
#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[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
|
||||
#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
|
||||
#set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
|
||||
#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
|
||||
#set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
|
||||
#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
|
||||
#set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
|
||||
#set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
|
||||
#set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
|
||||
#set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
|
||||
#set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
|
||||
#set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
|
||||
#set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs
|
||||
#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #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]
|
||||
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports kdata]
|
||||
|
||||
##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
|
112
Labs/12. Peripheral units/ps2_hex.txt
Normal file
112
Labs/12. Peripheral units/ps2_hex.txt
Normal file
@@ -0,0 +1,112 @@
|
||||
93 00 10 00
|
||||
13 01 d0 02
|
||||
93 01 00 08
|
||||
37 e2 00 00
|
||||
13 02 b2 06
|
||||
b7 e2 00 00
|
||||
93 82 42 07
|
||||
93 04 f0 0f
|
||||
13 03 00 08
|
||||
13 04 50 05
|
||||
13 0a e0 04
|
||||
93 05 60 01
|
||||
13 06 e0 01
|
||||
93 06 60 02
|
||||
13 07 50 02
|
||||
93 07 e0 02
|
||||
13 08 60 03
|
||||
93 08 d0 03
|
||||
13 09 e0 03
|
||||
93 09 60 04
|
||||
13 05 50 04
|
||||
93 03 00 04
|
||||
93 0a 00 02
|
||||
13 0b 00 01
|
||||
93 0c 80 00
|
||||
13 0d 40 00
|
||||
93 0d 20 00
|
||||
37 0e 00 03
|
||||
13 0e 0e 00
|
||||
b7 0e 00 04
|
||||
93 8e 0e 00
|
||||
23 22 1e 02
|
||||
23 a2 1e 02
|
||||
83 2b 4e 00
|
||||
e3 8e 0b fe
|
||||
03 2c 0e 00
|
||||
63 00 2c 04
|
||||
63 04 4c 04
|
||||
63 08 5c 04
|
||||
63 0c 8c 04
|
||||
63 00 4c 07
|
||||
63 06 ac 06
|
||||
63 08 bc 06
|
||||
63 0a cc 06
|
||||
63 0c dc 06
|
||||
63 0e ec 06
|
||||
63 00 fc 08
|
||||
63 02 0c 09
|
||||
63 04 1c 09
|
||||
63 06 2c 09
|
||||
63 08 3c 09
|
||||
6f ff 9f fb
|
||||
23 22 1e 02
|
||||
23 a2 1e 02
|
||||
6f ff 9f f2
|
||||
e3 84 61 fa
|
||||
b3 91 11 00
|
||||
6f ff 1f fa
|
||||
e3 8e 11 f8
|
||||
b3 d1 11 00
|
||||
6f ff 5f f9
|
||||
b3 e4 91 00
|
||||
23 a0 9e 02
|
||||
6f ff 9f f8
|
||||
b3 e4 91 00
|
||||
b3 84 34 40
|
||||
23 a0 9e 02
|
||||
6f ff 9f f7
|
||||
b3 0f 00 00
|
||||
6f 0f c0 04
|
||||
b3 0f 10 00
|
||||
6f 0f 40 04
|
||||
93 0f 20 00
|
||||
6f 0f c0 03
|
||||
93 0f 30 00
|
||||
6f 0f 40 03
|
||||
93 0f 40 00
|
||||
6f 0f c0 02
|
||||
93 0f 50 00
|
||||
6f 0f 40 02
|
||||
93 0f 60 00
|
||||
6f 0f c0 01
|
||||
93 0f 70 00
|
||||
6f 0f 40 01
|
||||
93 0f 80 00
|
||||
6f 0f c0 00
|
||||
93 0f 90 00
|
||||
6f 0f 40 00
|
||||
63 96 61 00
|
||||
23 ae fe 01
|
||||
6f ff df f1
|
||||
63 96 71 00
|
||||
23 ac fe 01
|
||||
6f ff 1f f1
|
||||
63 96 51 01
|
||||
23 aa fe 01
|
||||
6f ff 5f f0
|
||||
63 96 61 01
|
||||
23 a8 fe 01
|
||||
6f ff 9f ef
|
||||
63 96 91 01
|
||||
23 a6 fe 01
|
||||
6f ff df ee
|
||||
63 96 a1 01
|
||||
23 a4 fe 01
|
||||
6f ff 1f ee
|
||||
63 96 b1 01
|
||||
23 a2 fe 01
|
||||
6f ff 5f ed
|
||||
e3 98 11 ec
|
||||
23 a0 fe 01
|
||||
6f ff 9f ec
|
21
Labs/12. Peripheral units/sw_led.txt
Normal file
21
Labs/12. Peripheral units/sw_led.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
93 04 10 00
|
||||
13 09 a0 0a
|
||||
93 02 a0 0a
|
||||
13 19 89 00
|
||||
33 09 59 00
|
||||
93 09 50 55
|
||||
93 02 50 00
|
||||
93 99 49 00
|
||||
b3 89 59 00
|
||||
37 0e 00 01
|
||||
b7 0e 00 02
|
||||
03 2a 0e 00
|
||||
63 0a 2a 01
|
||||
63 0c 3a 01
|
||||
23 a0 4e 01
|
||||
23 a2 0e 00
|
||||
ef f2 df fe
|
||||
23 a2 9e 02
|
||||
ef f2 5f fe
|
||||
23 a2 9e 00
|
||||
ef f2 df fd
|
54
Labs/12. Peripheral units/sys_clk_rst_gen.v
Normal file
54
Labs/12. Peripheral units/sys_clk_rst_gen.v
Normal file
@@ -0,0 +1,54 @@
|
||||
module sys_clk_rst_gen#(
|
||||
parameter DIV_WIDTH = 4
|
||||
)(
|
||||
input ex_clk_i,
|
||||
input ex_areset_n_i,
|
||||
input [DIV_WIDTH-1:0] div_i,
|
||||
|
||||
output sys_clk_o,
|
||||
output sys_reset_o
|
||||
);
|
||||
|
||||
reg [1:0] ex_arstn_buf;
|
||||
reg [1:0] sys_rstn_buf;
|
||||
|
||||
wire ex_arstn_buffered;
|
||||
assign ex_arstn_buffered = ex_arstn_buf[1];
|
||||
assign sys_reset_o = !sys_rstn_buf[1];
|
||||
|
||||
always @(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
|
||||
|
||||
reg [DIV_WIDTH-1:0] cnt;
|
||||
reg clk_div;
|
||||
always@( 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;
|
||||
clk_div <= !clk_div;
|
||||
end else begin
|
||||
cnt <= cnt - 1;
|
||||
end
|
||||
end
|
||||
|
||||
BUFG clkbuf (.O(sys_clk_o),.I(clk_div));
|
||||
|
||||
always @(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[0], 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
108
Labs/12. Peripheral units/testbench.sv
Normal file
108
Labs/12. Peripheral units/testbench.sv
Normal file
@@ -0,0 +1,108 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company: MIET
|
||||
// Engineer: Nikita Bulavin
|
||||
//
|
||||
// Create Date:
|
||||
// Design Name:
|
||||
// Module Name: tb_riscv_unit
|
||||
// Project Name: RISCV_practicum
|
||||
// Target Devices: Nexys A7-100T
|
||||
// Tool Versions:
|
||||
// Description: tb for peripheral units
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module tb_riscv_unit();
|
||||
|
||||
localparam variant = 'd1; //1-SW_LED; 2-PS2_HEXLED; 3-UART;
|
||||
localparam button = 8'h16; //keyboard key code
|
||||
|
||||
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;
|
||||
|
||||
initial begin clk = 0; ps2_clk = 0; end
|
||||
|
||||
always #50 clk = ~clk;
|
||||
always #50000 if (variant == 2) if(starter || (cntr > 0)) ps2_clk = ~ps2_clk; else ps2_clk = 1;
|
||||
|
||||
logic [11:0] data;
|
||||
|
||||
initial begin
|
||||
resetn = 1;
|
||||
repeat(2)@(posedge clk);
|
||||
resetn = 0;
|
||||
repeat(2) @(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 )
|
||||
);
|
||||
|
||||
logic [3:0] cntr;
|
||||
|
||||
always @(negedge ps2_clk) begin
|
||||
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
|
||||
sw_i = 16'h0;
|
||||
cntr = 0;
|
||||
starter = 0;
|
||||
parity = !(^button);
|
||||
data = 0;
|
||||
case (variant)
|
||||
1: begin
|
||||
#10000;
|
||||
sw_i = 16'h01AA;
|
||||
#20000;
|
||||
sw_i = 16'hFF00;
|
||||
end
|
||||
2: begin
|
||||
data = {2'b11, parity, button, 1'b0};
|
||||
#100000;
|
||||
starter = 1;
|
||||
@(posedge ps2_clk)
|
||||
starter = 0;
|
||||
end
|
||||
3: begin
|
||||
|
||||
end
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
Reference in New Issue
Block a user