Лабораторная работа 7 "Внешняя память"
Ранее вы реализовали процессор архитектуры RISC-V с оговоркой что он не поддерживает инструкции sh, sb, lh, lhu, lb, lbu. Данное ограничение имеет две причины:
- вам нужен модуль, который будет будет определенным образом взаимодействовать с памятью в зависимости от конкретной инструкции загрузки или сохранения (модуль загрузки и сохранения, о котором будет рассказано на следующей лабораторной работе);
- вам нужна внешняя память, которая будет способна делать то, что от нее запросит модуль загрузки и сохранения.
Реализации такой памяти и будет посвящена эта лабораторная работа.
Цель
Описать внешнюю память данных, полностью поддерживающую побайтовую адресацию.
Допуск к лабораторной работе
Для успешного выполнения лабораторной работы, вам необходимо:
- выполнить лабораторную работу №3 "Регистровый файл и внешняя память";
- освоить оператор конкатенации (Concatenation.md).
Теория
В задании по реализации памяти инструкций лабораторной работы №3 байтовая адресация была описана следующим образом:
Байтовая адресация означает, что процессор способен обращаться к отдельным байтам в памяти (за каждым байтом памяти закреплен свой индивидуальный адрес).
Данное описание было дано не совсем корректным образом, чтобы в третьей лабораторной работе было более четкое понимание задания. В чем заключается некорректность? Процессор должен быть способен не только обращаться к отдельным байтам в памяти, но и обновлять в памяти любой отдельный байт, а так же считывать отдельные байты.
Вопрос считывания отдельного байта будет решаться модулем загрузки и сохранения, данному модулю будет достаточно возвращать все слово, содержащее запрашиваемый байт как это было сделано в рамках лабораторной работы №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-ой ячейки памяти.
Задание
Реализовать память данных с поддержкой обновления отдельных байт в выбранной ячейке памяти. Прототип модуля следующий (обратите внимание что название модуля отличается от названия памяти данных из третьей лабораторной работы — так мы сможем различать их):
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 тождественно равен единице.
Порядок выполнения работы
- Внимательно ознакомьтесь с заданием. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
- Реализуйте память данных. Для этого:
- В
Design Sourcesпроекта создайтеSystemVerilog-файлext_mem.sv. - Опишите в нем модуль памяти данных с таким же именем и портами, как указано в задании.
- Данный модуль будет очень похож на память данных из лабораторной работы №3 (в частности логика порта на чтение будет в точности повторять логику той памяти данных).
- Отличие заключается в двух новых сигналах
ready_oиbyte_enable_i.- Сигнал
ready_oтождественно равен единице. - Сигнал
byte_enable_iиспользуется в качестве сигнала, разрешающего запись (в случае операции записи) в конкретный байт ячейки памяти.
- Сигнал
- После описания памяти данных, её необходимо проверить с помощью тестового окружения.
- Тестовое окружение находится
здесь. - Для запуска симуляции воспользуйтесь
этой инструкцией. - Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (
tb_ext_mem). - Во время симуляции, вы должны прожать "Run All" и убедиться, что в логе есть сообщение о завершении теста!
- Тестовое окружение находится
- В