Хочу поподробнее рассказать, как работает видеодаптер, используемый в проекте USBTerm.

Мы уже не раз писали про всякие видеоконтроллеры на нашем сайте, вот хотя бы некоторые из статей:

Здесь же, в этой статье, я хочу сделать акцент на расчет пропускной способности и согласования записи и чтения в видеопамяти.

Итак, видеорежим.
Я делаю, так называемый HD-Ready: 1280x720 60Hz, 16 бит на пиксел, выход HDMI платы Марсоход3.
Выбор этого режима не случаен. Этот режим поддерживается большинством современных телевизоров и мониторов и у него не такие уж и высокие частоты. Спецификацию беру из VESA стандарта:

vesa

Тактовая частота для вывода пикселов 74,250 МГц. Это в общем-то не очень высокая частота для ПЛИС, но поскольку пикселы будут кодироваться для HDMI в сигналы TMDS (Transition-Minimized Differential Signaling), то выходная частота будет уже в 5 раз выше, то есть 370 МГц - это уже довольно много.

В спецификации VESA подробно описаны параметры видеосигналов, а именно параметры строчного и кадрового синхроимпульсов, а так же временные интервалы Active / Addressable Video, где происходит передача пикселов от видеоконтроллера к монитору.

vesa mode timing

Получается, что передача пикселов из памяти фреймбуффера в монитор длится почти 75% всего времени кадра. Пискелы можно не читать из видеопамяти и не передавать монитору во время кадрового и строчных синхроимпульсов, во время "бланков" - интервалы до и после синхроимпульсов (front & back porch). И что? Только в эти моменты времени можно писать изображения в видеопамять? Конечно нет. Если производительность видеопамяти гораздо выше требуемой для видеорежима, то писать в память можно и во время прямого хода развертки, однако, придется в систему добавить парочку FIFO.

Модули FIFO хороши тем, что они, позволяют передавать данные из одной части системы в другую на разных частотах, позволяют равномерно по времени распределять пики нагрузки.

Вот изображена блок-схема видеоадаптера.

block schema

Сразу видно, что в системе используется несколько частот.
Данные передаются из компьютера через шину USB2 и микросхему FTDI в режиме синхронного ФИФО. Тактовая частота передачи данных из FTDI - это 60МГц. То есть в пределе может передаваться 60 мегабайт в секунду. Конечно, такого в реальной жизни нет из-за особенностей протокола USB, из-за резервирования шины USB под разные устройства, однако где-то до 40 мегабайт/секунду на шине USB2, в принципе возможны.

Входные данные из FTDI попадают в первое FIFO - запись ведется на частоте FTDI чипа 2232H, то есть, 60МГц. Чтение же данных из FIFO происходит на частоте работы памяти 148МГц. На плате Марсоход3 используется 16-ти разрадная память SDRAM. Теоретически недостижимый предел производительности памяти 148 МГц умноженные на 2 байта => 296 МГб/сек (обычно существенно меньше, потому, что приходится переключать, активировать банки памяти, передавать другие команды SDRAM и т.д).

Таким образом, пропускная способность памяти гораздо больше входного потока. Однако, есть еще видеоконтроллер, который хочет читать из памяти во время активного хода развертки. Тут тоже стоит FIFO, которое работает на разных частотах. Чтение из FIFO идет с частотой pixel clock 74 МГц, запись в FIFO из видеопамяти идет на частоте 148 МГц. Поскольку пикселы у меня в видеорежиме 16-ти разрядные, то в "пике потребления" видеоконтроллеру нужно 74 * 2 = 148 мегабайт в секунду.

Если пропускная способность памяти 296Мгб/сек - 148Мгб/сек для видео, то остается еще где-то 148Мгб/сек на запись. А у меня FTDI в пределе может только 60Мгб/сек давать. Так, что запас по производительности памяти еще есть. Теоретически можно даже сделать не 16-ти битный цвет, а 24-битный цвет. Даже тогда останутся потенциальные 296-74*3=74МГбайта/сек на запись. Однако размер картинки в 24-х битном цвете в полтора раза больше, если пытаться делать анимацию, на экране, то это уже будет трудно, меньше кадров в секунду можно будет передать.

Конечно, это все довольно грубый подсчет, но я просто хочу проиллюстрировать методику.

Дальше нужно показать как же фифо работает в реальной системе. Эта временная диаграмма получена в результате симуляции проекта с помощью Icarus Verilog.

video fifo in framebuffer adapter

Модуль проекта videomem_rd_req следит за уровнем видео FIFO. Это FIFO хранит пикселы выдаваемые на экран и оно начинает опустошаться во время активного видео, когда пикселы передаются на экран. Входной сигнал videomem_rd_req.fifo_level показывает уровень наполненности фифо: 2'b01 - осталось меньше четверти, выдается read_request - сигнал запроса на чтение из памяти. Поскольку производительность памяти высока, то фифо удается быстро наполнить: fifo_level=2'b10 - это половина, fifo_level=2'b11 - это уже заполненность больше 3/4 объема FIFO, в этот момент запрос на чтение останавливается. Этот цикл повторяется во время всей развертки по строке. Пока read_request находится в низком уровне в эти окошки времени можно писать во фреймбуффер, тогда активизируется модуль записи ftdi.v. Он переносит накопленные данные из входного фифо в видеопамять.

Вот так, все довольно просто..

О проекте USBTerm.

Исходные тексты на GITHUB: https://github.com/marsohod4you/UsbHwThinClient4Vm

 


Добавить комментарий