Как реализовать процессор nand2tetris на реальной ПЛИС?

Я прошел курс nand2tetris (https://www.nand2tetris.org/course) с основной целью научиться собирать программный процессор на реальной ПЛИС.

Хотя курс был достаточно простым, теперь, когда я приступаю к реализации FPGA, я чувствую себя немного потерянным.

Я купил ПЛИС Intel de10 nano (http://de10-nano.terasic.com/) , и, имея некоторые знания Verilog из Uni, я смог загрузить Quartus Prime Lite и выполнить начальную загрузку с такими простыми вещами, как мигание светодиода и т. д.

Однако, когда дело доходит до реализации процессора, есть несколько вещей, которые мне не ясны:

  • Как реализовать память данных? Я видел, что к HPS FPGA подключен модуль DDR3. Это то, что мне нужно напрямую использовать? Могу ли я просто использовать большой 16-битный вектор регистров в HDL?
  • Как реализовать ПЗУ, откуда читается программа? И как я могу сохранить собранный двоичный файл, чтобы затем запустить цикл выборки-декодирования-выполнения?
  • Как реализовать экран и клавиатуру? Действительно, на плате есть еще и HDMI-контроллер: мне что, всю логику самому реализовывать?

Это основные вопросы, над которыми я сейчас бьюсь. Не могли бы вы указать мне на какой-либо ресурс, полезный для полного новичка?

Спасибо,


person Giuseppe Rossini    schedule 14.03.2021    source источник


Ответы (2)


Для чего-то столь же простого, как процессор от nand2tetris, вам вполне хватит блочной оперативной памяти, на DE10Nano ее предостаточно, вероятно, для всех ваших нужд. Плюс еще немного распределенной памяти.

В случае, если вам все же нужен доступ к DDR, DE10Nano — это SoC с жестким контроллером DDR, управляемым процессорной подсистемой. С ним очень легко взаимодействовать через шину Avalon (не беспокойтесь об AXI, если вам действительно не нужна максимально возможная производительность).

Для ПЗУ просто используйте LUT. Простой статический случай в Verilog будет переведен в эффективное ПЗУ на основе LUT.

Для доступа к HDMI на DE10Nano вы можете взглянуть на этот пример: "nofollow noreferrer">https://github.com/combinatorylogic/soc/blob/a1d282d793548030cba940496bed90ff3a29c0ba/backends/c2/hw/de10nano/vga1080p.v (вы также можете взглянуть на доступ к DDR в том же проект). Прежде чем вы сможете использовать HDMI, вам нужно настроить чип ADV7513 через i2c, см. копию библиотеки от Terasic в рамках того же проекта.

Для монохромного видео 800x600 вам подойдет блочная оперативная память. Для более высоких разрешений, как в приведенном выше примере, вам придется использовать DDR.

person SK-logic    schedule 16.03.2021
comment
Спасибо за ответ! Несколько уточняющих вопросов: блок RAM означает использование простого блока на основе reg[] в verilog? И что именно вы подразумеваете под ЛУТ? - person Giuseppe Rossini; 21.03.2021
comment
Вам нужно следовать нескольким простым правилам, чтобы убедиться, что адресуемый массив регистров синтезирован как блочная память. Например, см. стр. 20 документа intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/ - person SK-logic; 22.03.2021
comment
В качестве альтернативы вы можете самостоятельно создать экземпляр модуля блочной оперативной памяти поставщика. - person SK-logic; 22.03.2021
comment
@GiuseppeRossini для ПЗУ на основе LUT см. в этом примере: rel="nofollow noreferrer">github.com/combinatorylogic/soc/blob/ - person SK-logic; 22.03.2021
comment
Кроме того, вы всегда можете использовать блочное ОЗУ в качестве ПЗУ, так как вы можете загрузить его начальными значениями данных. В зависимости от того, какой ресурс более доступен — LUT или BRAM, вы можете решить, что использовать для реализации ПЗУ. - person SK-logic; 22.03.2021

Я закончил реализовывать аппаратную часть nand2tetris на небольшой fpga (ice40HX8K) и вот мои предложения:

A. Память Оригинальный nand2tetris использует две части памяти:

  1. ПЗУ для кода инструкции
  2. RAM для памяти данных

Оба могут быть реализованы с использованием BRAM-ячеек fpga. У них есть приятное свойство: BRAM может быть предварительно загружен данными при запуске. Это полезно для предварительной загрузки ПЗУ вашим кодом инструкции. Если у вас много BRAM, все в порядке. Моя плата (ice40HX8K-EVB от Olimex) имела только 8K x 16 бит BRAM. Поэтому я сделал следующее:

  1. Я использовал 512 x 16 бит BRAM в качестве ПЗУ с предустановленным загрузчиком (написанным на Hack-Assembler).
  2. остальная часть BRAM используется как RAM (7680 x 16 бит)
  3. На моей плате есть внешний чип SRAM (256 КБ x 16 бит). Я использовал это как память инструкций. При запуске загрузчик заполняет SRAM кодом приложения, а затем переключает SRAM на память инструкций.

Ваша плата имеет отдельный DRAM-чип. Вы также можете использовать это как память, но имейте в виду: использование DRAM намного сложнее, чем использование SRAM.

B. ввод/вывод nand2tetris имеет экран и прикрепленную к нему клавиатуру.

Простая в реализации альтернатива может быть следующей: реализовать небольшой UART, чтобы вы могли подключить свой ПК через терминал (например, screen /devttyACM0). Теперь вы можете общаться со своим Hack-CPU (работающим в fpga) во время выполнения. Я также использовал UART для загрузки Hack-Application во время загрузки.

Взгляните на мой репозиторий: https://gitlab.com/x653/nand2tetris-fpga

person user15424993    schedule 18.03.2021