У микросхем FPGA компании Gowin может быть встроенное динамическое ОЗУ, причем один из двух возможных типов:
- классическая SDR SDRAM типа MT48LC4M16 (64 мегабита);
- PSRAM (псевдо статическая) HyperRAM типа W955D8MBYA (2*32 мегабита ).
HyperRAM отличается от "классики" интерфейсом и наличием встроенной системы регенерации. Конкретно в чипе GW1NR-UV9QN88PC6/I5, установленном на нашей плате Марсоход3GW, есть ОЗУ именно второго типа.
На основе этой встроенной памяти создан этот проект фреймбуффера. Можно загружать битмапы прямо в чип FPGA платы Марсоход3GW и отображать их через HDMI выход на мониторе.
Проект находится в папке _hdmi_psram_fb репозитория гитхаб https://github.com/marsohod4you/Marsohod3GW.
В среде Gowin для работы с PSRAM имеется соответствующее IP-core. Оно может быть одноканальным или двухканальным. Ядро PSRAM устанавливается в проект примерно также как и rPLL через меню Tools -> IP Core Generator:
Так же как и в rPLL здесь есть много всяких фишек/плюшек, но, практически, ничего менять нельзя, за исключением Burst Mode во вкладке Options. Это самое «Mode» может быть — 16, 32, 64 или 128.
Сам модуль имеет совершенно несложный интерфейс . Есть шина адреса, шина данных и некоторое количество управляющих сигналов. В частности сигнал «cmd» - это тип команды. 1 — запись, 0 — чтение. Сигнал «cmd_en» - момент начала ее выполнения. Все операции пакетные и длинна пакета зависит от режима Burst Mode.
Операция записи в режиме Burst Mode - 16 выглядит так:
Начинается пакет записываемых данных в один момент с началом команды. Кроме того, есть сигнал «data_mask», с помощью которого можно защитить какие-то данные от записи.
Операция чтения выглядит похоже:
Всё почти так же, за тем исключением, что читаемые данные появляются не сразу, а через некоторое количество тактов. Это количество всегда постоянно, но, конкретная цифра нигде не указана. По результатам моих экспериментов ~16 тактов. Весь пакет данных из памяти сопровождается сигналом «rd_data_valid».
Хочу обратить внимание на то,что все это работает по клоку «clk_out» который является у модуля выходом,
и его частота в два раза меньше входного сигнала clk. Еще один важный момент, между двумя командами должен быть минимальный интервал, зависящий от Burst Mode:
Двухканальный модуль PSRAM отличается от одноканального наличием двух наборов сигналов шины и разрядностью слов данных. У одноканального слова по 64 бита , у двухканальных по 32.
В нашем демонстрационном проекте используется видеорежим 640х480 с разрешением по цвету RGB(565). Модуль памяти используется двухканальный, с Burst Mode - 128. То есть в каждом пакете данных будет по 32 32-х битных слова. На вход модуля подаем клок частотой 25 Мгц, и с такой-же частотой выводятся пиксели в нашем видеорежиме. Соответственно, выходные данные будут идти с частотой в два раза ниже, но по 32 бита,
то есть по 2 пикселя.
Логика работы следующая. В каждой строке есть видимая (640) и невидимая(160) части. Если заблаговременно (за 16 клоков) до начала видимой части строки подать команду чтения в один из каналов, то как раз в момент начала отображения строки на экран, начнут поступать данные из этого канала. Их будет 32 слова, то есть 64 пикселя. Если в другой канал подать команду чтения на 32 клока (64 пикселя) позже, то сразу после того, как закончатся данные из одного канала, начнут поступать данные из другого. Таким образом, чередуя команды чтения по обоим каналам, мы получаем непрерывный поток данных для отображения на экране. А за время невидимой части строки развертки можно выполнить одну операцию записи.
В нашем проекте выполняется запись только одного слова в какой-то один из каналов.
Изображение в плату мы будем передавать из компьютера через СОМ-порт на скорости 1 мегабит. Чтобы не заморачиваться с программированием со стороны компьютера, будем использовать стандартные 24-х битные битмапы, и передавать их командой «copy» из консоли. Удаление заголовка битмапа и преобразование RGB(888) в RGB(565) выполняется в самом проекте. Поскольку один экран в нашем видеорежиме занимает меньше мегабайта, то в нашу плату мы можем скопировать 8 разных картинок.
На демонстрационном видео, 6 картинок я загрузил заранее, и буду грузить седьмую.
Номер загружаемого фрейма видно на светодиодах:
PS: На самом деле наличие встроенной в FPGA чип памяти такого объёма это очень круто. 8 мегабайт это даже какой нибудь урезанный Linux можно попробовать запустить!
Подробнее...