mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 17:20:10 +00:00
ЛР13. Обновление тб и порядка выполнения задания
This commit is contained in:
@@ -154,31 +154,37 @@ _Рисунок 2. Карта памяти периферийных устрой
|
||||
|
||||
1. Внимательно ознакомьтесь с [примером описания модуля контроллера](../../Basic%20Verilog%20structures/Controllers.md).
|
||||
2. Внимательно ознакомьтесь со спецификацией контроллеров периферии своего варианта. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
|
||||
3. Реализуйте модули контроллеров периферии. Имена модулей и их порты будут указаны в [описании контроллеров](#описание-контроллеров-периферийных-устройств). Пример разработки контроллера приведен в [примере описания модуля контроллера](../../Basic%20Verilog%20structures/Controllers.md).
|
||||
3. Добавьте в проект пакет [`peripheral_pkg`](peripheral_pkg.sv). Данный пакет содержит старшие части адресов периферии в виде параметров, а также вспомогательные вызовы, используемые тестбенчем.
|
||||
4. Реализуйте модули контроллеров периферии. Имена модулей и их порты будут указаны в [описании контроллеров](#описание-контроллеров-периферийных-устройств). Пример разработки контроллера приведен в [примере описания модуля контроллера](../../Basic%20Verilog%20structures/Controllers.md).
|
||||
1. Готовые модули периферии, управление которыми должны осуществлять модули-контроллеры хранятся в папке `peripheral modules`.
|
||||
4. Обновите модуль `riscv_unit` в соответствии с разделом ["Дополнительные правки модуля riscv_unit"](#дополнительные-правки-модуля-riscv_unit).
|
||||
5. Обновите модуль `riscv_unit` в соответствии с разделом ["Дополнительные правки модуля riscv_unit"](#дополнительные-правки-модуля-riscv_unit).
|
||||
1. Подключите в проект файл `sys_clk_rst_gen.sv`.
|
||||
2. Добавьте в модуль `riscv_unit` входы и выходы периферии, а так же замените вход `rst_i` входом `resetn_i`. **Необходимо добавить порты даже тех периферийных устройств, которые вы не будете реализовывать**.
|
||||
3. Создайте в начале описания модуля `riscv_unit` экземпляр модуля `sys_clk_rst_gen`, скопировав приведенный фрагмент кода.
|
||||
4. Замените подключение тактового сигнала исходных подмодулей `riscv_unit` на появившийся сигнал `sysclk`. Убедитесь, что на модули, имеющие сигнал сброса, приходит сигнал `rst`.
|
||||
5. Интегрируйте модули контроллеров периферии в процессорную систему по приведенной схеме руководствуясь старшими адресами контроллеров, представленными на карте памяти ([_рис. 2_](../../.pic/Labs/lab_13_periph/fig_02.png)). Это означает, что если вы реализуете контроллер светодиодов, на его вход `req_i` должна подаваться единица в случае, если `mem_req_o == 1` и старшие 8 бит адреса равны `0x02`.
|
||||
6. Интегрируйте модули контроллеров периферии в процессорную систему по приведенной схеме руководствуясь старшими адресами контроллеров, представленными на карте памяти ([_рис. 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" также необходим файл, инициализирующий память данных (в модуле `data_mem` необходимо добавить вызов инициализирующей функции `$readmemh` в блоке `initial`).
|
||||
2. Для проверки тестбенч имитирует генерацию данных периферийных устройств ввода. Перед проверкой желательно найти в тестбенче `initial`-блок своего устройства ввода (`sw_block`, `ps2_block`, `uart_block`) — по этому блоку будет понятно, какие данные будет передавать устройство ввода. Именно эти данные в итоге должны оказаться на шине `mem_rd_i`.
|
||||
3. Для того, чтобы понять, что устройство работает должным образом, в первую очередь необходимо убедиться, что контроллер устройства ввода успешно осуществил прием данных (сгенерированные тестбенчем данные оказались в соответствующем регистре контроллера периферийного устройства) и выполнил запрос на прерывание.
|
||||
4. После чего, необходимо убедиться, что процессор среагировал на данное прерывание, и в процессе его обработки в контроллер устройства вывода были поданы выходные данные.
|
||||
5. Для того, чтобы лучше понимать как именно процессор будет обрабатывать прерывание, рекомендуется ознакомиться с исходным кодом исполняемой программы, расположенным в папке `firmware/software`.
|
||||
7. Проверьте работу процессорной системы с помощью моделирования.
|
||||
1. Для моделирования используйте тестбенч `lab_13_tb_system`.
|
||||
2. Для каждой пары контроллеров в папке `firmware/mem_files` представлены файлы, инициализирующие память инструкций. Обратите внимание, что для пары "PS2-VGA" также необходим файл, инициализирующий память данных (в модуле `data_mem` необходимо добавить вызов инициализирующей функции `$readmemh` в блоке `initial`).
|
||||
3. Для проверки тестбенч имитирует генерацию данных периферийных устройств ввода. Перед проверкой желательно найти в тестбенче `initial`-блок своего устройства ввода (`sw_block`, `ps2_block`, `uart_block`) — по этому блоку будет понятно, какие данные будет передавать устройство ввода. Именно эти данные в итоге должны оказаться на шине `mem_rd_i`.
|
||||
4. Для того, чтобы понять, что устройство работает должным образом, в первую очередь необходимо убедиться, что контроллер устройства ввода успешно осуществил прием данных (сгенерированные тестбенчем данные оказались в соответствующем регистре контроллера периферийного устройства) и выполнил запрос на прерывание.
|
||||
5. После чего, необходимо убедиться, что процессор среагировал на данное прерывание, и в процессе его обработки в контроллер устройства вывода были поданы выходные данные.
|
||||
6. Для того, чтобы лучше понимать как именно процессор будет обрабатывать прерывание, рекомендуется ознакомиться с исходным кодом исполняемой программы, расположенным в папке `firmware/software`.
|
||||
1. Общая логика программ для всех периферий сводится к ожиданию в бесконечном цикле прерывания от устройства ввода, после чего в процессе обработки прерывания процессор загружает данные от устройства ввода и (возможно преобразовав их) выдает их на устройство вывода.
|
||||
2. В случае правильной работы программы на временной диаграмме это будет отображено следующим образом: сразу после поступления прерывания от устройства ввода, на системной шине начинается операция чтения из устройства ввода (это легко определить по старшей части адреса, к которому обращается процессор), после чего выполняются операции записи в устройство вывода (аналогично, обращение к устройству вывода можно определить по адресу, к которому обращается процессор).
|
||||
6. При моделировании светодиодов лучше уменьшить значение, до которого считает счетчик в режиме "моргания" в 1000 раз, чтобы сократить время моделирования до очередного переключения светодиодов. Перед генерацией битстрима это значение будет необходимо восстановить, иначе моргание станет слишком быстрым и его нельзя будет воспринять невооруженным взглядом.
|
||||
7. При моделировании светодиодов лучше уменьшить значение, до которого считает счетчик в режиме "моргания" в 1000 раз, чтобы сократить время моделирования до очередного переключения светодиодов. Перед генерацией битстрима это значение будет необходимо восстановить, иначе моргание станет слишком быстрым и его нельзя будет воспринять невооруженным взглядом.
|
||||
|
||||
7. Переходить к следующему пункту можно только после того, как вы полностью убедились в работоспособности модуля на этапе моделирования (увидели корректные значения на выходных сигналах периферии, либо (если по сигналам периферии сложно судить о работоспособности), значениям в контрольных/статусных регистрах модуля-контроллера этой периферии). Генерация битстрима будет занимать у вас долгое время, а итогом вы получите результат: заработало / не заработало, без какой-либо дополнительной информации, поэтому без прочного фундамента на моделировании далеко уехать у вас не выйдет.
|
||||
8. Переходить к следующему пункту можно только после того, как вы полностью убедились в работоспособности модуля на этапе моделирования (увидели корректные значения на выходных сигналах периферии, либо (если по сигналам периферии сложно судить о работоспособности), значениям в контрольных/статусных регистрах модуля-контроллера этой периферии). Генерация битстрима будет занимать у вас долгое время, а итогом вы получите результат: заработало / не заработало, без какой-либо дополнительной информации, поэтому без прочного фундамента на моделировании далеко уехать у вас не выйдет.
|
||||
<!-- 1. Для каждой пары контроллеров периферии предложено две программы: с обновлением данных по опросу и по прерываниям. Запустите моделирование сначала для одной программы, затем для другой (для этого необходимо обновить файл, инициализирующий память инструкций). После проверки работоспособности процессора, сравните поведение сигналов LSU для этих программ. -->
|
||||
8. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе.
|
||||
9. Проверьте работу вашей процессорной системы на отладочном стенде с ПЛИС.
|
||||
9. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе.
|
||||
10. Проверьте работу вашей процессорной системы на отладочном стенде с ПЛИС.
|
||||
1. Обратите внимание, что в данной лабораторной уже не будет модуля верхнего уровня `nexys_...`, так как ваш модуль процессорной системы уже полностью самостоятелен и взаимодействует непосредственно с ножками ПЛИС через модули, управляемые контроллерами периферии.
|
||||
2. Для проверки периферии переключателей и светодиодов будет достаточно одного лишь отладочного стенда. Для проверки всей остальной периферии может могут потребоваться: компьютер (для uart_rx / uart_tx), клавиатура (для контролера клавиатуры) и VGA-монитор для VGA-контроллера.
|
||||
1. Чтобы проверить работоспособность контроллеров UART, необходимо запустить на компьютере программу Putty, в настройках программы указать настройки, которыми будет сконфигурирован программой ваш контроллер (либо указать значения, которыми сбрасываются регистры, если программа ничего не настраивает) и COM-порт, через который компьютер будет общаться с контроллером. Определить нужный COM-порт на операционной системе Windows можно через "Диспетчер устройств", который можно открыть через меню пуск.
|
||||
В данном окне необходимо найти вкладку "Порты (COM и LPT)", раскрыть ее, а затем подключить отладочный стенд через USB-порт (если тот еще не был подключен). В списке появится новое устройство, а в скобках будет указан нужный COM-порт.
|
||||
2. Не смотря на то, что описанный контроллер клавиатуры позволяет управлять клавиатурой с интерфейсом PS/2, некоторые платы (например Nexys A7) позволяют подключать вместо них клавиатуры с USB-интерфейсом. Дело в том, что PS/2 уже давно устарел и найти клавиатуры с таким интерфейсом — задача непростая. Однако протокол передачи по этому интерфейсу очень удобен для образовательны целей, поэтому некоторые производители просто ставят на платы переходник с USB на PS/2, позволяя объединить простоту разработки с удобством использования.
|
||||
|
||||
---
|
||||
|
||||
|
103
Labs/13. Peripheral units/lab_13.tb_system.sv
Normal file
103
Labs/13. Peripheral units/lab_13.tb_system.sv
Normal file
@@ -0,0 +1,103 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Project Name : Architectures of Processor Systems (APS) lab work
|
||||
* Organization : National Research University of Electronic Technology (MIET)
|
||||
* Department : Institute of Microdevices and Control Systems
|
||||
* Author(s) : Andrei Solodovnikov
|
||||
* Email(s) : hepoh@org.miet.ru
|
||||
|
||||
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
module lab_13_tb_system();
|
||||
|
||||
import peripheral_pkg::*;
|
||||
|
||||
logic clk_i;
|
||||
logic resetn;
|
||||
logic [15:0] sw_i;
|
||||
logic [15:0] led_o;
|
||||
logic ps2_clk;
|
||||
logic ps2_dat;
|
||||
|
||||
logic [ 6:0] hex_led_o;
|
||||
logic [ 7:0] hex_sel_o;
|
||||
logic rx_i;
|
||||
logic tx_o;
|
||||
|
||||
|
||||
initial begin clk_i = 0; end
|
||||
always #5ns clk_i = ~clk_i;
|
||||
|
||||
initial #4ms $finish();
|
||||
|
||||
initial begin
|
||||
resetn = 1;
|
||||
repeat(20)@(posedge clk_i);
|
||||
resetn = 0;
|
||||
repeat(20) @(posedge clk_i);
|
||||
resetn = 1;
|
||||
end
|
||||
|
||||
riscv_unit dut(
|
||||
.clk_i (clk_i ),
|
||||
.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_i);
|
||||
sw_i = 16'hdead;
|
||||
repeat(1000) @(posedge clk_i);
|
||||
sw_i = 16'h5555;
|
||||
repeat(1000) @(posedge clk_i);
|
||||
sw_i = 16'hbeef;
|
||||
repeat(1000) @(posedge clk_i);
|
||||
sw_i = 16'haaaa;
|
||||
end
|
||||
|
||||
initial begin: ps2_initial_block
|
||||
ps2_clk = 1'b1;
|
||||
ps2_dat = 1'b1;
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'h1C, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'hf0, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'h1C, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'h32, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'hf0, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'h32, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'h21, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'hf0, ps2_clk, ps2_dat);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
ps2_send_scan_code(8'h21, ps2_clk, ps2_dat);
|
||||
end
|
||||
|
||||
initial begin: uart_rx_initial_block
|
||||
rx_i = 1'b1;
|
||||
repeat(1000) @(posedge clk_i);
|
||||
uart_rx_send_char(8'h1c, 115200, rx_i);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
uart_rx_send_char(8'h0D, 115200, rx_i);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
uart_rx_send_char(8'h0D, 115200, rx_i);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
uart_rx_send_char(8'h7F, 115200, rx_i);
|
||||
repeat(1000) @(posedge clk_i);
|
||||
uart_rx_send_char(8'h7F, 115200, rx_i);
|
||||
end
|
||||
|
||||
endmodule
|
42
Labs/13. Peripheral units/peripheral_pkg.sv
Normal file
42
Labs/13. Peripheral units/peripheral_pkg.sv
Normal file
@@ -0,0 +1,42 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Project Name : Architectures of Processor Systems (APS) lab work
|
||||
* Organization : National Research University of Electronic Technology (MIET)
|
||||
* Department : Institute of Microdevices and Control Systems
|
||||
* Author(s) : Andrei Solodovnikov
|
||||
* Email(s) : hepoh@org.miet.ru
|
||||
|
||||
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
package peripheral_pkg;
|
||||
|
||||
localparam DMEM_ADDR_HIGH = 8'h00;
|
||||
localparam SW_ADDR_HIGH = 8'h01;
|
||||
localparam LED_ADDR_HIGH = 8'h02;
|
||||
localparam PS2_ADDR_HIGH = 8'h03;
|
||||
localparam HEX_ADDR_HIGH = 8'h04;
|
||||
localparam RX_ADDR_HIGH = 8'h05;
|
||||
localparam TX_ADDR_HIGH = 8'h06;
|
||||
localparam VGA_ADDR_HIGH = 8'h07;
|
||||
localparam TIMER_ADDR_HIGH = 8'h08;
|
||||
|
||||
task automatic ps2_send_scan_code(input logic [7:0] code, ref logic ps2_clk, ref logic ps2_dat);
|
||||
logic [11:0] data = {2'b11, !(^code), code, 1'b0};
|
||||
for(int i = 0; i < 11; i++) begin
|
||||
ps2_dat = data[i];
|
||||
#15us;
|
||||
ps2_clk = 1'b0;
|
||||
#15us;
|
||||
ps2_clk = 1'b1;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic uart_rx_send_char(input logic [7:0] char, input logic [31:0] baudrate, ref logic tx);
|
||||
logic [11:0] data = {2'b11, (^char), char, 1'b0};
|
||||
for(int i = 0; i < 12; i++) begin
|
||||
tx = data[i];
|
||||
#(1s/baudrate);
|
||||
end
|
||||
endtask
|
||||
|
||||
endpackage
|
@@ -1,124 +0,0 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Project Name : Architectures of Processor Systems (APS) lab work
|
||||
* Organization : National Research University of Electronic Technology (MIET)
|
||||
* Department : Institute of Microdevices and Control Systems
|
||||
* Author(s) : Andrei Solodovnikov
|
||||
* Email(s) : hepoh@org.miet.ru
|
||||
|
||||
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
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