И отново за VGA интерфейса
Бих желал да споделя личния си опит при извеждането на изображение на екран посредством VGA интерфейса. Разбирам, че тази задача е решавана неведнъж, от разнообразни хора и на друго съоръжение. Но има още доста какво да се каже.
На етажерката събира прахуляк сходна на показаната по-долу платка за премахване на неточности, на която няма нищо друго с изключение на FPGA и SDRAM (разбира се, без да броим бутоните, светодиодите и т.н.).
Налагаше се да направя план за извеждане на изображение на екран от платка, която няма сходен интерфейс и се постанова да предпочитам сред HDMI, DVI и VGA. Имах концепция за план, в който трябваше да отвеждам изображение на монитор; бих споделил, че неразделна част от плана е извеждането на монитора. Тъй като на платката няма интерфейс, трябваше да предпочитам сред HDMI, DVI и VGA. Предварително ще кажа, че въпреки интерфейсите да са разнообразни, те всъщност обезпечават едно и също нещо: три цветни линии (червена, синя, зелена) и два сигнала за синхронизация – синхронизация по редове и синхронизация по фрагменти.
Преглед на разновидностите
HDMI
След като прочетох за този интерфейс, се оказа, че той е сериен, което значи, че в случай че вземете резолюция на екрана 640×480 пиксела при кадрова периодичност 60Hz, изходната периодичност на пикселите е към 25MHz, а след серийния модул – всичките 250MHz. Освен това този интерфейс изисква TMDS модул, а аз въобще не желаех да се занимавам с него, тъй че на този стадий разглеждането на този интерфейс бе спряно.
DVI
Този интерфейс има няколко режима. Двата съществени са дигитален (DVI-D) и аналогов (DVI-A). Аналоговата алтернатива по принцип е същата като опцията VGA, по тази причина ще бъде прегледана по-късно. В рамките на този интерфейс, както и при HDMI, има LVDS линии, които също постановат потреблението на сериализатор и енкодер. Затова по същите аргументи (мързел) ще пропусна и този интерфейс.
VGA
Вероятно най-опростеният и най-старият интерфейс (също и част от DVI-A). За да се изведе изображение, би трябвало да се генерират три равнища на цвят (червен, наследник, зелен) и два синхронизиращи сигнала (прогресивен и кадър по кадър). И в този главен вид към този момент могат да се получат 8 разнообразни цвята. На изображението нагоре е показано разположението на изводите на интерфейса VGA при свързване към FPGA и оферти китайски модул с VGA. На входа на модула има три 8-битови цветови шини и два синхронизиращи сигнала (модулът има два чипа с повторители на сигнала и масив от резистори за образуване на нивото). Естествено, китайският модул е хубав и изумителен, само че аз потеглих по различен път – взех решение да сглобя всичко самичък.
Реализацията
След като прочетох няколко публикации в интернет по тематиката за извеждане на изображението на монитора, забелязах редица съществени особености:
VGA интерфейсът има стандарт за изхода (очевидно е, само че все пак). Всеки режим има своя лична дълготрайност на невидимите елементи на полето, периодичност на извеждане на пикселите и полярността на синхронизиращите сигнали. Така да вземем за пример за разграничителна дарба 640×480 полярността на тактовите сигнали 60Hz и 100Hz е различна В доста публикации се натъртва, че невидимите зони отдясно и отляво на работната зона би трябвало да бъдат ясно разграничени.
Този способ е малко сложен за схващане и реализация, по тази причина взех решение да употребявам друго показване:
Активната област се реалокира в горния ляв ъгъл, а полетата се демонстрират отдясно и изпод.
Друг главен миг е, че равнището на RGB сигналите е 0,7 V при входно противодействие 75 Ω, само че това разбрах по-късноЖитейски опит № 1
Въз основа на разположението на изводите (показано по-горе) могат да се употребяват 8 разнообразни цвята. Реших да употребявам разграничителна дарба 640×480 с периодичност на фрагментите 60Hz, като съгласно стандарта е ясно, че общата повърхност е 800×525 пиксела. Алгоритъмът за извеждане е извънредно банален, с два отвесни и хоризонтални брояча. Линиите се изчертават хоризонтално линия по линия (това е добре прочут факт) и до момента в който броячите са в границите на работната област (640×480) – изображението се извежда.
Ако във връзка с логаритъма всичко е ясно, в стандарта се показва и честотата на пикселите. Тя е 25,175 MHz. На този стадий към този момент стартира да се усеща болежка. В доста образци за планове с PLL на Altera е било допустимо да се генерира необятен диапазон от честоти, само че в моя случай PLL бе стеснен и не искаше да даде това, което ми трябваше. Чрез болежка и страдалчество сложих двата PLL поредно и получих 25,185 MHz. Като цяло допустимата неточност не е доста огромна – към 0,04% (на този стадий си помислих, че честотата би трябвало да е тъкмо както споделя стандартът, другояче картината ще е плаваща или въобще няма да се синхронизира). Но както се оказа, не бях прав…).
В последна сметка получих заветните осем линии:
Докато си играех, открих, че макар че стандартът VGA има сигнали за синхронизация, без които картината не се извежда (проверих по-късно…), а и по никакъв начин не е добре картината да приключва с черна лента. Веднага се скапва синхронизацията и мониторът я смята за невидима област и я скрива, оставяйки единствено 7 ленти. След като прочетох по тематиката и зададох неуместни въпроси на разнообразни хора, се оказа, че някои монитори се синхронизират и по един от цветовете.
Житейски опит № 2
Осемте цвята не ми бяха задоволителни и като цяло нямах задоволително линии на монитора. Но защото свързах интерфейса непосредствено, в последна сметка получих еднобитов цвят. След известно обсъждане взех решение да разширя диапазона благодарение на ШИМ. Вдигнах честотата на модула до 100,74 MHz и се пробвах да образувам RGB сигнали с разнообразни ширини на импулсите.
Мониторът се оказа по-умен от мен. Първия път той съумя да се приспособява към моя ШИМ и сътвори същата гладка картина като първия път, когато го пуснах без потребление на ШИМ. Но след редица насилствени ограничения мониторът въпреки всичко реагира единствено че за жалост не получих пъстър градиент. Получих накъсани линии. На изображението се пробвах да направя 4 ленти с друга ширина на импулса. Първата лента е без ШИМ, втората е с 25%, третата – с 50%, а четвъртата – със 75%. След като се поразрових в този вид, осъзнах, че ще би трябвало да направя един естествен ЦАП.
Житейски опит № 3
От института знаех, че има ЦАП на резистори, и че това е най-бързият ЦАП; с минуса, че е належащо резисторите да бъдат подбрани допустимо най-прецизно, като резултатът зависи от тази точност. В моя случай точността не е значима, най-важното е да наподобява правилно. Схемата на ЦАП от вида R-2R е добре известна в интернет и наподобява по следния метод:
Взех поялник и комплект резистори 1 КΩ и 2 КΩ и се заех с работата. Направих 5-битов ЦАП. Резултатът е следният:
След като свързах няколко кабела, го стартирах:
Снимката е направена в цялостен мрак. Отне ми известно време да се сетя да изгася осветлението и не осъзнах какво съм направил неправилно. Когато ревизирах запояването с мултицет, видях, че напрежението в ЦАП-а се трансформира, в случай че на входа приложа друга стойност. Тогава забелязах, че мониторът не е отмерено черен, а като че ли е разграничен на браншове, и тогава изключих светлината. Отново започнах да задавам серии от въпроси, които ме накараха да се усещам най-неудобно, тъй като разбирам тематиката и за какво не се бях сетил за това самичък, не знам. А казусът беше в това, че съпротивлението на приемника (в монитора за всеки RGB ред) беше 75 Ω, а аз свързах ЦАП със противодействие повече от 2 КΩ. В резултат на това генерираното напрежение в приемника не надхвърляше 123mV (в най-хубавия случай), до момента в който на мен ми бяха нужни 700mV.
Отново отворих браузъра, с цел да проуча въпроса – какъв ЦАП ми би трябвало, за може изображението да дава отговор на предстоящото от мен. Едни от разновидностите бе същият R2R ЦАП, само че с резистори с доста по-малко противодействие – от към 70-150 Ω. Вторият вид не с редом свързани резистори. Ето я схемата:
Този способ се употребява в доста платки за дебъгване, като да вземем за пример платката Altera. Естествено, без да се възнамерявам доста, направих сходен ЦАП с 5 бита на цвят:
И като резултат се получи първият съответен резултат:
На фигурата са показани 32786 нюанса (всеки цвят – наследник, зелен и червен – има 32 равнища на яркостта).
Житейски опит № 4
Сега остава нищо работа – единствено да настроим механизма за извеждане на изображението от буфера на паметта. Свързах чип SDRAM памет и описах автоматизма, който го запълва с кадър с градиент, сходен на тези нагоре. Описах и автоматизираната процедура, която чете фрагмента от паметта и го изпраща към модула с VGA излаз. Като цяло всичко проработи от първия път (е, знаете какво имам поради – нищо не работи от първия път). Но тук би трябвало да се разбере, че всичко се получи без изпиляване на нервите.
Като цяло изображението си е там, то е статично, което е индикация, че се актуализира вярно в паметта, и не е плаващо, тъй че прочитането е съответно. Но в случай че се вгледате деликатно, ще видите вълнообразни линии по границата на градиентите.
Тук би трябвало да се разбере, че планът ми към този момент се е увеличен – прибавих SDRAM контролер, няколко автомата, FIFO, обработка на бутони и намигване на светлини (като част от дебъгването), както и ChipScope. Тоест, когато описвах VGA модула настрана, нямаше нищо в допълнение и границите бяха равни, само че не щеш ли се това знамение се появи – и имам нова купчина въпроси.
След дълга полемика по тематиката бе изразена концепцията, че е належащо да се отстранен двата поредно свързани PLL-а. Първо, платката е китайска и е малко евентуално осцилаторът с периодичност 50 MHz да дава идеални стойности. Освен това самият PLL внася в допълнение вибриране, а като се има поради, че има два PLL модула, резултатът на вибриране става доста по-забележим.
В този миг изгубих визия от кое място да взема 25,175 MHz (които стандартът изисква), откакто PLL-ът не може да го обезпечи. В отчаянието си започнах обезверената стъпка (според мен) да настроя изходната периодичност на пикселите на 25 MHz (използвайки един PLL) при 640×[email protected] В последна сметка всичко стартира да работи, прелестно и безпрепятствено. За следващ път осъзнах, че мониторът е доста по-умен, в сравнение с си мислех!).
След това описах UART интерфейса, написах стратегия на QT за зареждане на изображението посредством UART на FPGA и съумях да заредя първия си миньон там!) Ето го миньона:
Цветовете малко се размиха, само че както се оказа по-късно, бях изгубил един обичай от цвета (от страната на компютъра). В резултат на това се загуби един канал, мисля, че беше зеленият. Но в последна сметка видеото стартира да наподобява доста добре.
Кодът
Модулът чете 16 бита данни от FIFO, конфигуриран в режим AXI-Stream. От които долните 15 бита са RGB, а горните 16 бита се употребяват за синхронизиране на фрагмента сред модулите. Само при положение, че има загуба на данни или някаква щета, модулът за VGA интерфейса прави синхронизация по старшия обичай. Той се подвига в края на фрагмента, като се извършва нещо като самобитен last.. Модулът осъществя VGA формат 640×[email protected] Hz по промишлен стандарт (тактова периодичност на пикселите 25,175 MHz). За да се приспособява към други режими, е належащо да се дефинират полярността на синхронизиращите импулси и размерът на изходната област.




