diff --git a/.github/SUMMARY.md b/.github/SUMMARY.md index 2480997..7e65bd3 100644 --- a/.github/SUMMARY.md +++ b/.github/SUMMARY.md @@ -49,7 +49,6 @@ - [Руководство по поиску ошибок](Vivado%20Basics/Debug%20manual.md) - [Руководство по прошивке ПЛИС](Vivado%20Basics/Program%20nexys%20a7.md) - [Заголовочные файлы в Verilog](Vivado%20Basics/Verilog%20Header.md) -- [Как добавить файл, инициализирующий память](Vivado%20Basics/How%20to%20add%20a%20mem-file.md) # Остальное diff --git a/Labs/03. Register file and memory/README.md b/Labs/03. Register file and memory/README.md index c2944b6..f631341 100644 --- a/Labs/03. Register file and memory/README.md +++ b/Labs/03. Register file and memory/README.md @@ -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("",,,);` +`$readmemh("",,,);` Однако на деле обычно используются только обязательные аргументы: -`$readmemb("",);` +`$readmemh("",);` Пример описанной выше памяти: @@ -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. После описания памяти инструкций, её необходимо проверить с помощью тестового окружения. diff --git a/Labs/03. Register file and memory/program.txt b/Labs/03. Register file and memory/program.mem similarity index 100% rename from Labs/03. Register file and memory/program.txt rename to Labs/03. Register file and memory/program.mem diff --git a/Labs/03. Register file and memory/tb_instr_mem.sv b/Labs/03. Register file and memory/tb_instr_mem.sv index c467f26..c9a3359 100644 --- a/Labs/03. Register file and memory/tb_instr_mem.sv +++ b/Labs/03. Register file and memory/tb_instr_mem.sv @@ -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}]; diff --git a/Labs/04. Primitive programmable device/README.md b/Labs/04. Primitive programmable device/README.md index 7bdbe52..a1e9712 100644 --- a/Labs/04. Primitive programmable device/README.md +++ b/Labs/04. Primitive programmable device/README.md @@ -293,7 +293,7 @@ Разработать процессор `CYBERcobra`, объединив ранее разработанные модули: -- Память инструкций (проинициализированную в двоичном формате файлом [`example.txt`](example.txt)) +- Память инструкций (проинициализированную в двоичном формате файлом [`example.mem`](example.mem)) - Регистровый файл - Арифметико-логическое устройство - 32-битный сумматор @@ -331,13 +331,13 @@ endmodule 5. Мультиплексор, выбирающий источник записи в регистровый файл. 3. После описания модуля, его необходимо проверить с помощью [`тестового окружения`](../../Basic%20Verilog%20structures/Testbench.md). 1. Тестовое окружение находится [`здесь`](tb_cybercobra.sv). - 2. Программа, которой необходимо проинициализировать память инструкций находится [`здесь`](example.txt). Алгоритм работы программы приведен в разделе [`Финальный обзор`](#финальный-обзор). + 2. Программа, которой необходимо проинициализировать память инструкций находится [`здесь`](example.mem). Алгоритм работы программы приведен в разделе [`Финальный обзор`](#финальный-обзор). 3. Для запуска симуляции воспользуйтесь [`этой инструкцией`](../../Vivado%20Basics/Run%20Simulation.md). 4. Перед запуском симуляции убедитесь, что выбран правильный модуль верхнего уровня. 5. **Во время симуляции, вы должны прожать "Run All" и убедиться, что в логе есть сообщение о завершении теста!** 6. В этот раз, в конце не будет сообщения о том, работает ли ваше устройство или в нем есть ошибки. Вы должны самостоятельно проверить работу модуля, перенеся его внутренние сигналы на временную диаграмму, и [проверив](../../Vivado%20Basics/Debug%20manual.md) логику их работы. 4. Добавьте в проект модуль верхнего уровня ([nexys_cybercobra_demo.sv](board%20files/nexys_cybercobra_demo.sv)), соединяющий процессор с периферией в ПЛИС. Описание работы модуля находится [здесь](board%20files) -5. Замените содержимое файла, инициализирующего память инструкций новой программой, которая размещена [`здесь`](board%20files/demo.txt). +5. Замените содержимое файла, инициализирующего память инструкций новой программой, которая размещена [`здесь`](board%20files/demo.mem). 6. Убедитесь, что у файла, инициализирующего память инструкций выставлен тип `Memory Initialization Files`, а не `Memory File`. 7. Подключите к проекту файл ограничений ([nexys_a7_100t.xdc](board%20files/nexys_a7_100t.xdc)), если тот еще не был подключен, либо замените его содержимое данными из файла к этой лабораторной работе. 8. Проверьте работу процессора в ПЛИС. diff --git a/Labs/04. Primitive programmable device/board files/README.md b/Labs/04. Primitive programmable device/board files/README.md index 04754d1..98ffaf8 100644 --- a/Labs/04. Primitive programmable device/board files/README.md +++ b/Labs/04. Primitive programmable device/board files/README.md @@ -2,7 +2,7 @@ Если вы не понимаете, что лежит в этой папке, или если надо вспомнить, как прошить ПЛИС, можно воспользоваться [`этой инструкцией`](../../../Vivado%20Basics/Program%20nexys%20a7.md) -Файл [`nexys_cybercobra_demo.sv`](nexys_cybercobra_demo.sv), который нужно запускать с [`демонстрационным файлом инструкций`](demo.txt), является демонстрацией возможностей кобры, реализующий лишь декодирование выходных значений в формат для отображения на семисегментных индикаторах, а вся логика работы реализована инструкциями в текстовом файле. +Файл [`nexys_cybercobra_demo.sv`](nexys_cybercobra_demo.sv), который нужно запускать с [`демонстрационным файлом инструкций`](demo.mem), является демонстрацией возможностей кобры, реализующий лишь декодирование выходных значений в формат для отображения на семисегментных индикаторах, а вся логика работы реализована инструкциями в текстовом файле. Сначала выводится приветствие `≡ALOHA≡`, меняя положение восьми правых переключателей, последовательно нажимая на кнопку `BTND` (на рисунке выделена синим цветом), можно включать или выключать `один` из выбранных сегментов. Кнопка `CPU RESET` (на рисунке выделена красным цветом) возвращает все исходное состояние. Попробуйте погасить все слово, а потом снова его зажечь. diff --git a/Labs/04. Primitive programmable device/board files/demo.txt b/Labs/04. Primitive programmable device/board files/demo.mem similarity index 100% rename from Labs/04. Primitive programmable device/board files/demo.txt rename to Labs/04. Primitive programmable device/board files/demo.mem diff --git a/Labs/04. Primitive programmable device/example.txt b/Labs/04. Primitive programmable device/example.mem similarity index 100% rename from Labs/04. Primitive programmable device/example.txt rename to Labs/04. Primitive programmable device/example.mem diff --git a/Labs/04. Primitive programmable device/Индивидуальное задание/README.md b/Labs/04. Primitive programmable device/Индивидуальное задание/README.md index dc81a8e..dbf6398 100644 --- a/Labs/04. Primitive programmable device/Индивидуальное задание/README.md +++ b/Labs/04. Primitive programmable device/Индивидуальное задание/README.md @@ -154,10 +154,10 @@ cyberconverter принимает до двух аргументов. Поряд cyberconverter --help ``` -2. Преобразование программы, записанной в файле `test.txt`, с записью результата в файл `program.txt`: +2. Преобразование программы, записанной в файле `test.txt`, с записью результата в файл `program.mem`: ```bash - cyberconverter test.txt program.txt + cyberconverter test.txt program.mem ``` 3. Если не указан второй аргумент, результат будет записан в файл: @@ -169,7 +169,7 @@ cyberconverter принимает до двух аргументов. Поряд Результат будет записан в файл `test_converted.txt`. -4. Если программа будет запущена без аргументов, то исходным файлом будет считаться файл `program.txt`. +4. Если программа будет запущена без аргументов, то исходным файлом будет считаться файл `program.mem`. В случае отсутствия исходного файла, наличия неподдерживаемых символов или неверной длины инструкции будет выведено сообщение об ошибке. diff --git a/Labs/04. Primitive programmable device/Индивидуальное задание/cyberconverter.cpp b/Labs/04. Primitive programmable device/Индивидуальное задание/cyberconverter.cpp index f689b74..747b936 100644 --- a/Labs/04. Primitive programmable device/Индивидуальное задание/cyberconverter.cpp +++ b/Labs/04. Primitive programmable device/Индивидуальное задание/cyberconverter.cpp @@ -15,11 +15,11 @@ void print_help(const std::string program_name) cout << "in hex-format.\n\n"; cout << "If output file omitted, the _converted.\n"; cout << "will be produced.\n\n"; - cout << "If input file omitted, program.txt will be used.\n\n"; + cout << "If input file omitted, program.mem will be used.\n\n"; cout << "Example:\n\n"; - cout << program_name << " open \"program.txt\" and produce \"program_converted.txt\"\n"; + cout << program_name << " open \"program.mem\" and produce \"program_converted.mem\"\n"; cout << program_name << " test.txt open \"test.txt\" and produce \"test_converted.txt\"\n"; - cout << program_name << " test.txt myname.dat open \"test.txt\" and produce \"myname.dat\"\n"; + cout << program_name << " test.txt myname.mem open \"test.txt\" and produce \"myname.mem\"\n"; } @@ -39,8 +39,8 @@ int main(int argc, char ** argv) switch (argc) { case 1: - ifname = "program.txt"; - ofname = "program_converted.txt"; + ifname = "program.mem"; + ofname = "program_converted.mem"; break; case 2: if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) diff --git a/Labs/04. Primitive programmable device/Индивидуальное задание/example.txt b/Labs/04. Primitive programmable device/Индивидуальное задание/example.mem similarity index 100% rename from Labs/04. Primitive programmable device/Индивидуальное задание/example.txt rename to Labs/04. Primitive programmable device/Индивидуальное задание/example.mem diff --git a/Labs/06. Datapath/board files/README.md b/Labs/06. Datapath/board files/README.md index ac2597c..54d84b1 100644 --- a/Labs/06. Datapath/board files/README.md +++ b/Labs/06. Datapath/board files/README.md @@ -2,4 +2,4 @@ Если вы не понимаете, что лежит в этой папке, или если надо вспомнить, как прошить ПЛИС, можно воспользоваться [`этой инструкцией`](../../../Vivado%20Basics/Program%20nexys%20a7.md) -Файл [`nexys_riscv_unit.sv`](nexys_riscv_unit.sv), который нужно запускать с [`демонстрационным файлом инструкций`](../program.txt), является демонстрацией работы вашего ядра, каждое нажатие на BTND формирует тактовый импульс, впоследствии пошагово переходя по инструкциям, которые в свою очередь отображаются на семисегментных индикаторах. +Файл [`nexys_riscv_unit.sv`](nexys_riscv_unit.sv), который нужно запускать с [`демонстрационным файлом инструкций`](../program.mem), является демонстрацией работы вашего ядра, каждое нажатие на BTND формирует тактовый импульс, впоследствии пошагово переходя по инструкциям, которые в свою очередь отображаются на семисегментных индикаторах. diff --git a/Labs/06. Datapath/program.txt b/Labs/06. Datapath/program.mem similarity index 100% rename from Labs/06. Datapath/program.txt rename to Labs/06. Datapath/program.mem diff --git a/Labs/11. Interrupt integration/README.md b/Labs/11. Interrupt integration/README.md index 33bef00..f96c401 100644 --- a/Labs/11. Interrupt integration/README.md +++ b/Labs/11. Interrupt integration/README.md @@ -21,4 +21,4 @@ 1. Обратите внимание, что что в модуле `riscv_core` появились новые входные и выходные сигналы: `irq_req_i` и `irq_ret_o`. Эти сигналы должны быть использованы при подключении `riscv_core` в модуле `riscv_unit`. 1. Ко входу `irq_req_i` должен быть подключен провод `irq_req`, другой конец которого пока не будет ни к чему подключен (в следующей лабораторной это будет изменено). 2. К выходу `irq_ret_o` необходимо подключить провод `irq_ret`, который также пока не будет использован. -2. После интеграции модулей, проверьте процессорную систему с помощью [программы](irq_program.txt), текст которой [был представлен](../10.%20Interrupt%20subsystem#пример-обработки-перехвата) в ЛР10 с помощью предоставленного [тестбенча](tb_irq_unit.sv). +2. После интеграции модулей, проверьте процессорную систему с помощью [программы](irq_program.mem), текст которой [был представлен](../10.%20Interrupt%20subsystem#пример-обработки-перехвата) в ЛР10 с помощью предоставленного [тестбенча](tb_irq_unit.sv). diff --git a/Labs/11. Interrupt integration/irq_program.txt b/Labs/11. Interrupt integration/irq_program.mem similarity index 100% rename from Labs/11. Interrupt integration/irq_program.txt rename to Labs/11. Interrupt integration/irq_program.mem diff --git a/Labs/Made-up modules/lab_03.instr_mem.sv b/Labs/Made-up modules/lab_03.instr_mem.sv index 502639b..f878b3e 100644 --- a/Labs/Made-up modules/lab_03.instr_mem.sv +++ b/Labs/Made-up modules/lab_03.instr_mem.sv @@ -9,7 +9,7 @@ module instr_mem( `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}]; diff --git a/Vivado Basics/How to add a mem-file.md b/Vivado Basics/How to add a mem-file.md deleted file mode 100644 index 7cb6e10..0000000 --- a/Vivado Basics/How to add a mem-file.md +++ /dev/null @@ -1,35 +0,0 @@ -# Как добавить файл с содержимым памяти в проект - -Представим ситуацию. Сел, значит, ты делать процессор на ПЛИС, делал-делал, и наконец сделал, прошил его в ПЛИС, но как запустить на нем программу? - -Благо, в ПЛИС предусмотрена возможность инициализировать (то есть задавать начальные значения) блочную память начальными значениями. Хранит она их рядом со своей прошивкой. При подаче питания на ПЛИС она конфигурирует себя из энергонезависимой памяти, и инициализирует блочную память. - -Программу (то, чем нужно проинициализировать память) нужно подсунуть до этапа сборки прошивки в виде текстового файла, в котором данные представлены ASCII-символами в двоичном или 16-ричном виде. В требуемом verilog-модуле необходимо указать какую память в модуле и из какого файла нужно инициализировать. Вот пример объявления памяти RAM с восьмью 32-битными ячейками: - -``` verilog -reg [31:0] RAM [0:7]; -initial $readmemh("my_program.txt", RAM); -``` - -В данном примере в память, именуемую RAM, помещаются значения из файла с названием my_program.txt. Файл не обязательно должен покрывать всю область памяти, количество строк может быть любым между 0 и максимумом. Но длинна строк должна строго соответствовать разрядности ячеек инициализируемой памяти. `$readmemh` для 16-ричнного представления чисел в файле, `$readmemb` – для файлов с двоичной записью. - -Кроме озвученного нужно сообщить САПРу, что файл памяти относится к проекту, и что он – файл памяти, а не какой-то другой. Для этого надо сделать два действия: - -1. Добавить файл в проект в качестве `Design-файла` -2. Указать в его свойствах тип файла `Memory Initialization Files` - -Файл в проект добавляется точно так же, как при создании Verilog-файла. - -![../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_1.png](../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_1.png) - -Дальше надо добавить файл с содержимым памяти. Обрати внимание, чтобы его можно было выбрать, нужно поставить в фильтрах `All Files`, как на картинке снизу. - -![../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_2.png](../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_2.png) - -После добавления файла в проект он отобразится в окне `Sources`, в папке `Text`. Чтобы поменять тип файла на нужный, необходимо выделить этот файл, нажав на него, после чего в окне `Source File Properties`, во вкладке `Properties` найти свойство `FILE_TYPE` и заменить его на `Memory Initialization Files`. Описанное отмечено на картинке далее. - -![../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_3.png](../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_3.png) - -Если после изменений файл переместился в папку `Memory Initialization Files` в окне `Sources`, значит все сделано правильно! - -![../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_4.png](../.pic/Vivado%20Basics/How%20to%20add%20a%20mem-file/how_to_mem_4.png) diff --git a/Vivado Basics/README.md b/Vivado Basics/README.md index 1ff82f3..3956843 100644 --- a/Vivado Basics/README.md +++ b/Vivado Basics/README.md @@ -14,5 +14,4 @@ 7. [Разобраться с ошибками, при попытке открыть схему / запустить симуляцию](Elaboration%20failed.md) 8. [Находить и исправлять ошибки дизайна, найденные тестовым окружением](Debug%20manual.md) 9. [Добавить заголовочный файл в проект Vivado](Verilog%20Header.md) -10. [Добавить файл инициализации памяти в проект Vivado](How%20to%20add%20a%20mem-file.md) -11. [Понять как работают этапы элаборации/синтеза/имплементации](Implementation%20steps.md) +10. [Понять как работают этапы элаборации/синтеза/имплементации](Implementation%20steps.md)