mirror of
https://github.com/MPSU/APS.git
synced 2025-09-16 17:40:41 +00:00
ЛР7. Добавление методички
This commit is contained in:
committed by
GitHub
parent
70d703154e
commit
c2d903da7c
@@ -1 +1,86 @@
|
|||||||
# PLACEHOLDER
|
# Лабораторная работа 7 "Внешняя память"
|
||||||
|
|
||||||
|
Ранее вы реализовали процессор архитектуры RISC-V с оговоркой что он не поддерживает инструкции `sh`, `sb`, `lh`, `lhu`, `lb`, `lbu`. Данное ограничение имеет две причины:
|
||||||
|
|
||||||
|
- вам нужен модуль, который будет будет определенным образом взаимодействовать с памятью в зависимости от конкретной инструкции загрузки или сохранения (**модуль загрузки и сохранения**, о котором будет рассказано на [следующей](../08.%20Load-store%20unit) лабораторной работе);
|
||||||
|
- вам нужна внешняя память, которая будет способна делать то, что от нее запросит модуль загрузки и сохранения.
|
||||||
|
|
||||||
|
Реализации такой памяти и будет посвящена эта лабораторная работа.
|
||||||
|
|
||||||
|
## Цель
|
||||||
|
|
||||||
|
Описать внешнюю память данных, полностью поддерживающую побайтовую адресацию.
|
||||||
|
|
||||||
|
## Допуск к лабораторной работе
|
||||||
|
|
||||||
|
Для успешного выполнения лабораторной работы, вам необходимо:
|
||||||
|
|
||||||
|
- выполнить [лабораторную работу №3](../03.%20Register%20file%20and%20memory/) "Регистровый файл и внешняя память";
|
||||||
|
- освоить оператор конкатенации ([Concatenation.md](../../Basic%20Verilog%20structures/Concatenation.md)).
|
||||||
|
|
||||||
|
## Теория
|
||||||
|
|
||||||
|
В задании по реализации памяти инструкций [лабораторной работы №3](../03.%20Register%20file%20and%20memory/) байтовая адресация была описана следующим образом:
|
||||||
|
|
||||||
|
> Байтовая адресация означает, что процессор способен обращаться к отдельным байтам в памяти (за каждым байтом памяти закреплен свой индивидуальный адрес).
|
||||||
|
|
||||||
|
Данное описание было дано не совсем корректным образом, чтобы в третьей лабораторной работе было более четкое понимание задания. В чем заключается некорректность? Процессор должен быть способен не только **обращаться** к отдельным байтам в памяти, но и **обновлять** в памяти любой отдельный байт, а так же **считывать** отдельные байты.
|
||||||
|
|
||||||
|
Вопрос считывания отдельного байта будет решаться модулем загрузки и сохранения, данному модулю будет достаточно возвращать все слово, содержащее запрашиваемый байт как это было сделано в рамках лабораторной работы №3.
|
||||||
|
|
||||||
|
Нас интересует возможность памяти обновлять любой из байт в слове. Для этого используется специальный сигнал, который называется `byte_enable_i`. Разрядность этого сигнала равна числу байт в ячейке памяти (в данном случае разрядность `byte_enable_i` составляет 4). Вы можете представить `byte_enable_i`, как 4 провода, каждый из которых является сигналом разрешения записи для 8-ми D-триггеров, формирующих соответствующий этому проводу байт.
|
||||||
|
|
||||||
|
При этом не стоит забывать о том, что записью управляет еще и сигнал `write_enable_i`, определяющий режим работы памяти: запись или чтение.
|
||||||
|
|
||||||
|
Таким образом, для каждого байта `addr_i / 4`-ой ячейки памяти:
|
||||||
|
|
||||||
|
**если** `write_enable_i` равен единице **и** соответствующий этому байту бит сигнала `byte_enable_i`, то в данный байт памяти записывается соответствующий байт сигнала `write_data_i`.
|
||||||
|
|
||||||
|
При этом значение `byte_enable_i` может быть любым: если `byte_enable_i == 4'b1001` (при `write_enable == 1'b1`), то данные должны быть записаны в старший и младший байты `addr_i / 4`-ой ячейки памяти.
|
||||||
|
|
||||||
|
## Задание
|
||||||
|
|
||||||
|
Реализовать память данных с поддержкой обновления отдельных байт в выбранной ячейке памяти. Прототип модуля следующий (обратите внимание что название модуля отличается от названия памяти данных из третьей лабораторной работы — так мы сможем различать их):
|
||||||
|
|
||||||
|
```SystemVerilog
|
||||||
|
module ext_mem(
|
||||||
|
input logic clk_i,
|
||||||
|
input logic mem_req_i,
|
||||||
|
input logic write_enable_i,
|
||||||
|
input logic [ 3:0] byte_enable_i,
|
||||||
|
input logic [31:0] addr_i,
|
||||||
|
input logic [31:0] write_data_i,
|
||||||
|
output logic [31:0] read_data_o,
|
||||||
|
output logic ready_o
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Как и память данных из лабораторной работы №3, память данных в данной лабораторной состоит из 4096-и 32-разрядных ячеек и обладает портом синхронного чтения, выдающим данные по следующим правилам:
|
||||||
|
|
||||||
|
- В случае `mem_req_i == 0` или `write_enable_i == 1` (т.е. когда не выполняется операция чтения), на выходе `read_data_o` должно оказаться значение `32'hfa11_1eaf`.
|
||||||
|
- В случае, если `mem_req_i == 1` и значение `addr_i` **попадает** в диапазон `[0:16383]` (4096*4-1), на выходе `read_data_o` должно оказаться значение ячейки по адресу в 4 раза меньше пришедшего.
|
||||||
|
- В случае, если `mem_req_i == 1` и значение `addr_i` **не попадает** в диапазон `[0:16383]`, на выходе `read_data_o` должно оказаться магическое число `32'hdead_beef`.
|
||||||
|
|
||||||
|
Данные условия должны проверяться **строго** в указанном порядке (с указанным **приоритетом**) с помощью цепочки `if-else-if-else`, причем обязательно с блоками `else`.
|
||||||
|
|
||||||
|
Иными словами, логика реализации порта на чтение повторяет эту логику из памяти данных лабораторной работы №3 (можно скопировать эту логику).
|
||||||
|
|
||||||
|
Если `mem_req_i == 1` и `write_enable_i == 1` (т.е. если происходит запрос на запись в память), то необходимо обновить данные в тех байтах `addr_i / 4`-ой ячейки памяти, которые соответствуют единичным битам сигнала `byte_enable_i`.
|
||||||
|
|
||||||
|
Сигнал `ready_o` тождественно равен единице.
|
||||||
|
|
||||||
|
## Порядок выполнения работы
|
||||||
|
|
||||||
|
1. Внимательно ознакомьтесь с заданием. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
|
||||||
|
2. Реализуйте память данных. Для этого:
|
||||||
|
1. В `Design Sources` проекта создайте `SystemVerilog`-файл `ext_mem.sv`.
|
||||||
|
2. Опишите в нем модуль памяти данных с таким же именем и портами, как указано в задании.
|
||||||
|
1. Данный модуль будет очень похож на память данных из лабораторной работы №3 (в частности логика порта на чтение будет в точности повторять логику той памяти данных).
|
||||||
|
2. Отличие заключается в двух новых сигналах `ready_o` и `byte_enable_i`.
|
||||||
|
1. Сигнал `ready_o` тождественно равен единице.
|
||||||
|
2. Сигнал `byte_enable_i` используется в качестве сигнала, разрешающего запись (в случае операции записи) в конкретный байт ячейки памяти.
|
||||||
|
3. После описания памяти данных, её необходимо проверить с помощью тестового окружения.
|
||||||
|
1. Тестовое окружение находится [`здесь`](tb_ext_mem.sv).
|
||||||
|
2. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md).
|
||||||
|
3. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (`tb_ext_mem`).
|
||||||
|
4. **Во время симуляции, вы должны прожать "Run All" и убедиться, что в логе есть сообщение о завершении теста!**
|
||||||
|
Reference in New Issue
Block a user