mirror of
https://github.com/MPSU/APS.git
synced 2025-09-16 01:30:10 +00:00
Переход на использование mem-файлов (#38)
Раньше в вивадо была проблема с использованием mem-файлов. Они нормально моделировались, но при этом не использовались в синтезе, пока им не выставишь тип "Memory Initialization File". Однако с выставлением этого типа файл нельзя было открыть в вивадо (и даже поменять тип этого файла). Поэтому, все файлы в курсе носили расширение .txt, чтобы их можно было легко открыть в любом другом редакторе, а в вивадо выставлялся злополучный тип "Memory Initialization File" вручную. Сейчас же, судя по всему, вивадо нормально выполняет синтез и с "Memory File" тоже, а значит нет нужды в каком-либо изменении типов, лишь бы файлы носили расширение .mem. При этом файлы этого типа можно открывать и редактировать в редакторе вивадо.
This commit is contained in:
committed by
Andrei Solodovnikov
parent
6b2f0c2bab
commit
1bb2fdd323
@@ -153,7 +153,9 @@ module mem16_20 ( // создать блок с именем
|
||||
endmodule
|
||||
```
|
||||
|
||||
В случае реализации ПЗУ нет необходимости в описании входов для записи. В таком случае описание памяти занимает всего пару строк. Чтобы инициализировать такую память (то есть поместить в нее начальные значения, чтобы было что из нее читать), требуемое содержимое нужно добавить к прошивке, вместе с которой данные попадут в ПЛИС. Для этого в проект добавляется текстовый файл с содержимым памяти (более подробно об этом в [`Как добавить файл с содержимым памяти в проект`](../../Vivado%20Basics/How%20to%20add%20a%20mem-file.md)). Для того, чтобы отметить данный файл в качестве инициализирующего память, необходимо использовать одну из двух системных функций: `$readmemh` и `$readmemb`. `$readmemh` используется для файлов, описывающих содержимое памяти 16-ричными цифрами, в то время как `$readmemb` используется для файлов, описывающих содержимое памяти двоичными цифрами. Любую из этих системных функций необходимо поместить внутрь блока `initial`. У этих системных функций есть два обязательных аргумента:
|
||||
В случае реализации ПЗУ нет необходимости в описании входов для записи, поэтому описание памяти занимает всего пару строк. Чтобы проинициализировать такую память (то есть поместить в нее начальные значения, которые можно было бы из нее читать), требуемое содержимое нужно добавить к прошивке, вместе с которой данные попадут в ПЛИС. Для этого в проект добавляется текстовый файл формата `.mem` с содержимым памяти. Для того, чтобы отметить данный файл в качестве инициализирующего память, можно использовать системную функцию `$readmemh`.
|
||||
|
||||
У данной функции есть два обязательных аргумента:
|
||||
|
||||
- имя инициализирующего файла
|
||||
- имя инициализируемой памяти
|
||||
@@ -163,13 +165,13 @@ endmodule
|
||||
- стартовый адрес, начиная с которого память будет проинициализирована данным файлом (по-умолчанию равен нулю)
|
||||
- конечный адрес, на котором инициализация закончится (даже если в файле были ещё какие-то данные).
|
||||
|
||||
Пример полного вызова одной из этих системных функций выглядит так:
|
||||
Пример полного вызова выглядит так:
|
||||
|
||||
`$readmemb("<data file name>",<memory name>,<start address>,<end address>);`
|
||||
`$readmemh("<data file name>",<memory name>,<start address>,<end address>);`
|
||||
|
||||
Однако на деле обычно используются только обязательные аргументы:
|
||||
|
||||
`$readmemb("<data file name>",<memory name>);`
|
||||
`$readmemh("<data file name>",<memory name>);`
|
||||
|
||||
Пример описанной выше памяти:
|
||||
|
||||
@@ -184,8 +186,8 @@ module rom16_8 (
|
||||
logic [7:0] ROM [0:15]; // создать память с 16-ю 8-битными ячейками
|
||||
|
||||
initial begin
|
||||
$readmemh("mem.txt", ROM); // поместить в память RAM содержимое
|
||||
end // файла mem.txt
|
||||
$readmemh("rom_data.mem", ROM); // поместить в память RAM содержимое
|
||||
end // файла rom_data.mem
|
||||
|
||||
|
||||
assign read_data1 = R0M[addr1]; // реализация первого порта на чтение
|
||||
@@ -194,7 +196,7 @@ module rom16_8 (
|
||||
endmodule
|
||||
```
|
||||
|
||||
Содержимое файла `mem.txt`, к примеру может быть таким (каждая строка соответствует значению отдельной ячейки памяти, начиная со стартового адреса):
|
||||
Содержимое файла `rom_data.mem`, к примеру может быть таким (каждая строка соответствует значению отдельной ячейки памяти, начиная со стартового адреса):
|
||||
|
||||
```hex
|
||||
FA
|
||||
@@ -204,6 +206,8 @@ endmodule
|
||||
A7
|
||||
```
|
||||
|
||||
**Для того, чтобы при сборке модуля не было проблем с путями, по которым будет искаться данный файл, обычно его необходимо добавить в проект. В случае Vivado, чтобы тот распознал этот файл как инициализирующий память, необходимо чтобы у этого файла было расширение `.mem`.**
|
||||
|
||||
## Задание по реализации памяти
|
||||
|
||||
Необходимо описать на языке SystemVerilog три вида памяти:
|
||||
@@ -307,7 +311,7 @@ mоdulе rf_r𝚒sсv(
|
||||
1. В `Design Sources` проекта с предыдущих лаб, создайте `SystemVerilog`-файл `instr_mem.sv`.
|
||||
2. Опишите в нем модуль памяти инструкций с таким же именем и портами, как указано в задании.
|
||||
1. Сперва необходимо создать память (массив регистров). Как это сделать, сказано в разделе [описание памяти на языке SystemVerilog](#описание-памяти-на-языке-systemverilog). Разрядность ячеек памяти должна быть 32 бита, количество ячеек — 1024.
|
||||
2. Добавить в проект [`файл с содержимым памяти инструкций`](program.txt)([`как добавить файл, инициализирующий память`](../../Vivado%20Basics/How%20to%20add%20a%20mem-file.md)). Данный файл будет использоваться при вызове системной функции `$readmemh` в описании памяти инструкций.
|
||||
2. Добавить в проект [`файл с содержимым памяти инструкций`](program.mem). Данный файл будет использоваться при вызове системной функции `$readmemh` в описании памяти инструкций.
|
||||
3. К созданной памяти необходимо подключить выход модуля `read_data_o`. При подключении должен быть использован вход модуля `addr_i`, значение которого должно быть уменьшено в 4 раза (побайтовая адресация).
|
||||
4. При реализации выхода `read_data_o` помните, что обращаясь к ячейке памяти, вам необходимо использовать `[11:2]` биты адреса.
|
||||
3. После описания памяти инструкций, её необходимо проверить с помощью тестового окружения.
|
||||
|
@@ -60,7 +60,7 @@ module instr_mem_ref(
|
||||
`define asdasdhkjasdsa (34 >> `cdyfguvhbjnmk)
|
||||
|
||||
reg [31:0] RAM [0:1023];
|
||||
initial $readmemh("program.txt", RAM);
|
||||
initial $readmemh("program.mem", RAM);
|
||||
|
||||
always_comb begin
|
||||
read_data_o['h1f:'h1c]=RAM[{2'b00, addr_i[5'd28^5'o27:2]}][{5{1'b1}}:{3'd7,2'b00}];
|
||||
|
Reference in New Issue
Block a user