Merhaba, Ziyaretçi. Lütfen giriş yapın veya üye olun.

Kullanıcı adınızı, parolanızı ve aktif kalma süresini giriniz

  Gelişmiş Arama
insanın içinde varsa, commodore.gen.tr açığa çıkarır bunu.. bir nevi retro olaylarının dolunayıyız.(Arda)
commodore.gen.trCommodoreCommodore DonanımFPGA Günlükleri - I, II, III ve IV (FPGA ile HDMI Görüntü Üretme) SON
Sayfa: [1] 2 3 ... 18   Aşağı git
Yazdır
Gönderen Konu: FPGA Günlükleri - I, II, III ve IV (FPGA ile HDMI Görüntü Üretme) SON  (Okunma Sayısı 52806 defa)
0 Üye ve 1 Ziyaretçi konuyu incelemekte.
delimawi
Uzman
*****
Mesaj Sayısı: 1.580



Üyelik Bilgileri
« : Şubat 23, 2016, 11:21:08 ÖÖ »

Merhaba.

Yıllar sonra tekrar C64'ümle çeşitli projeler geliştirmek üzere bir araya geldiğimden beri, bir çok retrocunun yüzleştiği bir problemle ben de karşılaştım. Bir ara birşeyler düşünülmek üzere aklımın bir köşesinde yatıyordu. Biliyorsunuz C64 ve benzeri konsollar, zamanın arabirimleri olan composite, s-video yada şanslı isek RGB olarak çıkış veriyorlar. Bu arabirimler aslında cihaz gerçek bir CRT ekrana bağlandığında gayet güzel yada bir başka deyiş ile, bizim o zamanlardan aşina olduğumuz bilindik kendine has yatay çizgili (raster yada scanline) görüntülerini üretiyorlar. Ancak artık günümüzde CRT monitör bulmak neredeyse imkansız, bulsak bile zaten hem yer  hem de açıkçası bazı sağlık endişelerinden ötürü kullanmak pek uygun değil. Bu noktada aslında şanslıyız diyebiliriz, zira güncel LCD tabanlı tüm TV ve birçok monitörde composite, scart ve hatta component girişleri mevcut. Gel gelelim bu girişleri kullanarak eski günlere yolculuğa çıktığımızda, soğuk, düz, "aşırı kaliteli" yada bazen aksine çok kötü resample edilmiş görüntülerle karşılaşıyoruz.

Temelde bunun nedeni zaten belli ve gerçek bir çözüm üretmek mümkün değil. Zira CRT görüntüyü satır satır tarayarak oluşturuyorken, LCD tabanlı sistemlerde native resolution dediğimiz sabit bir piksel çözünürlüğü var ve tarama frekansı hem çok daha yüksek hem de görüntü aslında satır satır çizilerek oluşturulmuyor. Bizim girdiğimiz örneğin composite video sinyali TV yada monitör içerisinde önce resample/upsample denilen işlemlerden geçiriliyor ve LCD'nin native resolution değerine çevriliyor, sonra da görüntü oluşturuluyor. İşte bu çevirim işlemi esnasında, TV içerisinde kullanılan donanım ve gömülü yazılım ve koşan algoritmalarının kalitesi mertebesinde bir görüntü alıyoruz. Ben bugüne kadar beni gerçek anlamda tatmin edecek bir görüntüye rastlamadım.

Peki buna bir çözüm üretilebilir mi? Aslında evet, birçok emulatörün yaptığı gibi, scanline'lar emule edilip yeniden yaratılabilir. Burada çok detaya girmeyeceğim, dediğim gibi bu konuda yapılmış birçok çalışma hatta donanım projeleri de mevcut. Peki ben ne yapmak istiyorum? Ben C64 iç işleyişine fazla bulaşmadan, video çıkışını alıp, bunu güncel bir arabirim olan HDMI formatına gerçek zamanlı olarak çevirebilen, çok da pahalı olmayan bir arabirim tasarlamayı hedef seçtim. Burada salt çevrim yanısıra aynı zamanda yapabilirsem scanline emulasyonunu da işin içerisine katmayı düşünüyorum. Proje başarı ile sonlanırsa, C64'lerimizden, HDMI girişi olan tüm TV ve monitörlerde tatminkar bir görüntü alabileceğiz. Bonus olarak da, belki projeyi C64 haricindeki diğer sistemlerde kullanılmak üzere daha genel amaçlı bir hale getirmek mümkün olabilir.

Artık hedef belli olduğuna göre biraz daha teknik detaya inebiliriz. Composite > HDMI çevrimi aslında temelde iki farklı yöntem ile gerçekleştirilebilir.

Birinci yöntem de tüm frame'i önce decode (sample) ederiz, bunu bir framebuffer RAM'de saklar ve çıkış birimi tarafından tekrar HDMI olarak encode ederiz. Bu yöntemin avantajı giriş sinyaline tam olarak senkronize olmak gerekmiyor. Ayrıca giriş sinyali ile çıkış sinyali timing ve format olarak birbirlerinden tamamen farklı olabiliyor. Örneğin NTSC görüntüyü 800x600 haline vb çevirebiliyoruz. Dez avantajı ise en az 1 frame lik bir gecikme oluyor. Ayrıca sistemimizde tüm frame'i saklayacak büyüklükte bir RAM ihtiyacı doğuruyor.

İkinci yöntem ise aslında scandoubler olarak bildiğimiz yöntem. Bu yöntem ile örneğin C64'ten gelen 1 satırlık sinyal sample edilip, karşı tarafa ard arda gelen iki satır olarak gönderiliyor. Bu sayede düşey çözünürlük iki katı hale getirilmiş oluyor. Bu yöntemin avantajı çok daha sınırlı "sadece iki scanline saklayabilecek kadar" bir RAM gerektirmesi ve gecikmenin "neredeyse" hiç olmaması. Tabiki dezavantaj olarak da giriş sinyali ile çıkış sinyali arasında belirli bir uyum olması gerekiyor ve sinyaller tam olarak senkronize olmak durumunda. Aynı zamanda tam da yeri gelmişken Composite sinyalin interlaced olması ve düz ekranlara progresive görüntü verilmesinin daha sağlıklı olması gibi bir kavram daha var ancak buna yeri geldiğinde daha detaylı değineceğim. Son olarak bu yöntem bir de bonus ile beraber geliyor. Input edilen her bir satırın iki satır olarak gönderileceğinden bahsetmiştim. İşte tam burada eğer satırlardan birinin ışık değerini daha düşük gönderirsek, çakma da olsa bir scanline effeck elde etmiş oluyoruz. Deneyip göreceğiz...

Peki bu işler için ne tarz bir donanım ihtiyacımız var.

Öncelike analog gelen bir görüntüyü dijital halde işleyebilmek için decode etmeliyiz. Yani analogtan dijitale, olduğu gibi, sıkıştırmadan çevirmeliyiz. Bunun için bir video decoder chip kullanacağız. Henüz sipariş etmedim ama ilk yaptığım üstün körü araştırma ile Texas Instruments'in TVP5151 entegresi bu işe uygun görünüyor. "Ultralow-Power NTSC/PAL/SECAM Video Decoder". Tekli alımlar digikey fiyatı 5-6 USD civarı. Bir başka alternatif ise Intersil firmasının TW9990 entegresi. "Low Power NTSC/PAL/SECAM Video Decoder with Differential CVBS Inputs". Gene tekli alımlarda 5-6 USD fiyatlı bu entegrenin anladığım kadarı ile S-Video desteği de mevcut. C64 için bu yöntem daha tatminkar bir sonuç verebilir, bakacağız...

Sonrasında, elde ettiğimiz dijital görüntüyü işlemek için oldukça hızlı bir DSP, ASIC yada artık çok erişilebilir olan FPGA tarzı bir birime ihtiyacımız olacak. Buna da değineceğiz.

Görüntüyü işlerken daha önce bahsettiğimiz üzere kısıtlı da olsa bir RAM belleğimiz olmalı.

Son olarak işlenmiş dijital görüntüyü HDMI olarak göndermek için de bir HDMI transmitter entegresi kullanabiliriz.

Aslında bu son üç maddeyi özellikle detaya inmeden hızlı hızlı geçtim. Öncelikle, günümüz FPGA chipleri içerisinde aslında bir miktar kullanılabilir RAM var. Hatta kullanılmayan logic bloklar bile ek RAM olarak kullanılabiliyor. Bunun yanı sıra, HDMI dediğimiz arabirim ise aslında salt dijital bir format. Yani aslında uygun donanım FPGA içerisinde tasarlanırsa ayrıca bir HDMI transmitter kullanmadan bu sinyali elde etmek mümkün. Tüm bu gerçekleri bir araya getirdiğimizde, tek bir FPGA chip ile, hem görüntü işleme, hem FrameBuffer RAM hem de HDMI çıkış üretilmesi mümkün. Hadi o zaman FPGA'lere bakalım...

Kabaca FPGA, içerisinde binlerce logic blok tabir ettiğimiz hücre bulunan boş bir chip. Çok uygun bir benzetme olmayacak ama beyindeki nöronlara benzetebiliriz bunları. Biz her biri arasındaki bağlantıları (beyindeki sinapslara benzetilebilir) belirleyerek, sonuçta bu chipin ne işe yarayacağını tanımlayıp programlıyoruz. Tabi bu işler için kullanılan bir çok yazılım ve hatta standartlaşmış HDL tabir ettiğimiz diller mevcut. Detaya çok girmiyorum, proje ilerledikçe bakarız. Şu an için bilmemiz gereken, FPGA, mikroişlemci gibi satır satır program işleten bir chip değil, aksine programlandığı şekilde davranan bir donanım.

Projenin kabaca yöntemine de karar verdikten sonra yavaş yavaş ellerimizi kirletmeye başlayabiliriz. Açıkçası ben daqha önce projelerimde CPLD ve FPGA kullandım. Ama FPGA konusunda daha yolun çok başlarındayım. Bu proje boyunca elde ettiğim tecrübeleri bu sayflarda "FPGA Günlükleri" adı altında paylaşmayı hedefliyorum. Bu proje için elimde mevcut olan Altera CycloneII veya CycloneIV serisi FPGA'ler ile ilerleyeceğim. Bu kartların Çin üretimlerini Aliexpress yada Ebay'den uygun fiyatlı bulmak mümkün. Pahalı FPGA geliştirme kitleri edinmeye gerek olmadığına inanıyorum.

http://www.ebay.com/itm/EP1C3-FPGA-Development-Learn-Core-Board-ALTERA-Cyclone-JTAG-Quartus-II-CPLD-/281090549542?hash=item41724d6726:g:WkoAAOxy4c5RxPwx
http://www.ebay.com/itm/EP2C5T144-ALTERA-FPGA-Cyclone-IIMinimum-System-Development-Board-/321944799604?hash=item4af567c974:g:QcsAAOSwnH1WaShq
http://www.ebay.com/itm/EP4CE6-EP4CE6E22C8N-ALTERA-FPGA-Cyclone-IV-Development-Evaluation-Board-Core-Kit-/231074176951?hash=item35cd181fb7:g:D0UAAOSwYIhWjb~K

Tabi yoksa bir de USB programlayıcı ihtiyacı olacak. Bu durumda aşağıdaki gibi bir bundle daha uygun olabilir.

http://www.ebay.com/itm/EP4CE6-Mini-Board-USB-Blaster-Altera-Cyclone-IV-FPGA-CPLD-Nano-Size-/111838281376?hash=item1a0a14bea0:g:uvsAAOSwv0tVN1dT

Son olarak ücretsiz olan "Quartus II Web Edition" yazılımını ALTERA'nın sitesinden indirmemiz gerekiyor. Burada dikkatli olmak lazım zira son versiyonu değil, kullanmayı düşündüğünüz FPGA'leri destekleyen sürümü indirmek gerekiyor. Ben CycloneII ve CycloneIV üzerinde çalışacağım için v13.0sp1 i kullanıyorum. v15'i indirmeyin zira downloadlar çok büyük, 1.5GB ları bulabiliyor, kotanıza yazık olmasın.

Kısa olmasını hedeflediğim ama beceremediğim bu uzun giriş yazısından sonra, ilk olarak FPGA ile HDMI görüntü üretmek üzere hazırladığım ikinci yazıya kadar hoşçakalın.
"FPGA Günlükleri II" de görüşmek üzere...

2.Bölüm (FPGA ile görüntü üretme)
http://www.commodore.gen.tr/forum/index.php?topic=12046.msg137482#msg137482

3.Bölüm (TVP5150 Entegresi ile PAL Video Capture ve FPGA ile işleme)
http://www.commodore.gen.tr/forum/index.php?topic=12046.msg138109#msg138109
« Son Düzenleme: Mart 09, 2016, 22:22:21 ÖS Gönderen: delimawi » Logged

delimawi
Uzman
*****
Mesaj Sayısı: 1.580



Üyelik Bilgileri
« Yanıtla #1 : Şubat 23, 2016, 12:55:10 ÖS »

Bu arada birkaç test. Aşağıda şu ana kadar denediğim ve hedeflediğim görüntü örnekleri var. Foto çekilirken ve boyut ayarlaması yaparken biraz bozuldular ama kıyaslama açısından fikir veriyor.



Sol üstteki örnek, C64'ü doğrudan TV'nin composite girişine bağladığımda aldığım görüntü. Çok kötü. Hatta tersine italik bir hal almış karakterler. Tabiri caiz ise çamur gibi.

Sağ üstteki ise, aşağıdaki AV2HDMI mini çeviricisi ile aldığım görüntü. ÇEvirici üzerinde 720p ve 1080p switch var. Ancak sadece 720p de iken görüntü alabildim. Zaman zaman C64 çıkışını secam olarak algılayıp siyah beyaz bir görüntü üretiyor. Aslında çalıştığı zamanlarda görüntü fena değil. Beklediğimden iyi sonuç aldım. Bu çevirici 50TL ye satılıyor. Ama duyduğum kadarı ile sahteleri mevcutmuş. Dikkatli olmak lazım. Sonuç olarak istediğim görüntü bu da değil...



Sol alttaki görüntü ise, C64'ü AverTVBox 9 ile VGA'e çevirip, VGA LCD monitor ile aldığım görüntü. Hemen hemen en iyi sonucu şu ana kadar bununla aldım. Ama gene scanlinelar yok tabiki. Ayrıca her ne hikmet ise AverTV Box genelde C64 çıkışını detect etmiyor. 4-5 kere denemem gerekiyor görüntü alabilmek için.

Sağ alttaki ise, VICE emuden aldığım bir screenshot. Temelde buna yakın bir sonuç istiyorum.
Logged

joker_
Genel Yönetici
*****
Mesaj Sayısı: 2.123



Üyelik Bilgileri
« Yanıtla #2 : Şubat 23, 2016, 13:25:16 ÖS »

Araya girip konuyu bölmeyeyim dedim. Fakat dayanamadım. Abi resmen devrim niteliğinde bir proje bu Heyecanla takipteyim.
Logged
yavuzg
Genel Yönetici
*****
Mesaj Sayısı: 4.492



Üyelik Bilgileri
« Yanıtla #3 : Şubat 23, 2016, 15:33:08 ÖS »

Konu benim de zamanında bolca araştırma yapıp daha sonra dönerim diye bir yerlere park ettiğim bir proje. Heyecanla takip ediyor olacağım...

Bu arada ben bir scandoubler düşünmüştüm ve CPLD/FPGA tecrübem olmadığından ayrı ayrı parçalar kullanarak yapmayı planlamıştım. Çıkışı da direk HDMI (digital) değil bir DAC ile bitirmeyi planlamıştım.

Senin yaklaşımın hepimizi bir dertten kurtaracaktır. Yansımaları büyük olur zira konuyu "çok" araştırdım ve "open hardware" bulabildiğim malzeme çok azdı. Hele FPGA çözümü var ama kimse tasarımı paylaşmamış. Gerçi hatırladığım kadarıyla ya Altera'nın ya da bir başkasının resmi geliştirme kitinin örnek tasarım kütüphanesinde vardı bir upscaler/scandouble tasarımı...

Neyse, uzatmayayım, ben Composite=>RGB decoder olarak Fransız NES'de kullanılan Sony CXA1621S'i kullanmaya karar vermiştim. Eski bir tasarım elbette ama modern decoder'ların vereceği görüntü kalitesinden ziyade tasarımda zamanın teknolojisinden bir esinti kullanmanın daha "retro" bir görüntü verebileceğini düşünmüştüm...

Yani Fransız NES'i olanlar bilir, SCART'tan decode edilmiş RGB görüntüsü gayet başarılı... CXA1621S (daha çok V7021 diye geçiyor) tabanlı NES decoder devresi de şu:

http://mall.fc2.com/item/tansei/1423/


Logged

delimawi
Uzman
*****
Mesaj Sayısı: 1.580



Üyelik Bilgileri
« Yanıtla #4 : Şubat 23, 2016, 15:59:51 ÖS »

Araya girip konuyu bölmeyeyim dedim. Fakat dayanamadım. Abi resmen devrim niteliğinde bir proje bu Heyecanla takipteyim.

Ne demek, yorumlara her zaman açığım ve ihtiyacım var zaten. Paylaşıyorum ki birlikte fikirleri olgunlaştıralım...

@yavuzg, abi bu chipin esamesini bulmak artık mümkün mü bilmiyorum. Kahkaha Gerçi anladığım kadarıyla ve aslında belki de yakışanı da o, düşündüğün tasarım oldukça analog bir çevrim. Bu entegre RGB analog çıkış üretiyor. Sanırım bu aşamadan sonra DAC ile digitize edip, logic olarak işleyerek tersine ADC ile analog çevrim planlamıştın. RGB kanalları da muhtemelen en az 8 bit ile sample edildiğinde oldukça kaliteli bir sonuç alınır düşüncesindeyim. (24Bit RGB)

Bense daha minimal ve digital domainde çözmeye çalıştığım için, sinyali alır almaz hemen 4:2:2 YUV a çevirip, FPGA içerisinde işlemeyi planlıyorum. Demin elimde ne olabilir diye bakarken, ucuz bir composite>USB capture kartı içerisinde, gene eskilerden kalan SAA7113 entegresi buldum . Belki günlükte yazdığım iki entegreden önce bununla bir deneme yaparım. Zira bu hazır elimde mevcut, diğerlerini sipariş edip bekleyeceğim. Senin düşüncene kıyasla YUV 4:2:2 malesef aslında biraz daha düşük kaliteli kalıyor ama tekrar analoga çevrim yapmayacağım için de generasyon kaybı bir nebze daha düşük olacak. Bakalım sonuç nasıl olacak birlikte göreceğiz.

Bu arada ben de bakındım bazı çalışmalar yapılmış. Ben şimdilik fpga4fun sitesindeki HDMI örneği üzerine gidiyorum. Öncelikle FPGA ile istediğim çözünürlükte bir pattern üretmeyi deneyeceğim. Bu pattern şu an için external bir video sinyaline locked olmayacak tabiki. Ama çözünürlük olarak 576p sinyal üretmeyi deneyeceğim. Sonrasında bu sinyali girişteki video sinyaline pll ile lock olarak üretmeye gelecek sıra...
Logged

Levent (Lvnt)
Uzman
*****
Mesaj Sayısı: 1.280



Üyelik Bilgileri
« Yanıtla #5 : Şubat 23, 2016, 17:54:55 ÖS »

Başarılar dilerim, heyecanla hepsini okudum. Aklıma ilk gelen hdmi lag oldu, bunu önlemek için oyun konsollarında bazı yöntemler falan kullanmışlardı, direkt hdmi çıkış üretmek mi, konsola özel özel hdmi çıkış sistemi mi, ps3'ün ilk zamanlarında bu muhabbet dönüyordu. Herhalde lag olmaması için optimize edilmiş direkt hdmi protokolü üreten birşeylerdi. Umarım yanlış hatırlamıyorumdur.
Şöyle karıştırayım ortalığı biraz, başınıza iş açılsın 
Şaka bir yana umarım başarırsınız, ya da forumca hep beraber başarırız ne bileyim, kolay gelsin
Logged

Use the brute force, Luke
MeG
Üye4
***
Mesaj Sayısı: 591


Super Kahraman


Üyelik Bilgileri WWW
« Yanıtla #6 : Şubat 23, 2016, 19:04:16 ÖS »


Scanline için bir öneri de isteğe bağlı olabilmesi.
Yani bir switch vasıtası ile scanline olup olmaması seçilebilse harika olur.


Projede başarılar dilerim.
Logged
delimawi
Uzman
*****
Mesaj Sayısı: 1.580



Üyelik Bilgileri
« Yanıtla #7 : Şubat 23, 2016, 19:53:09 ÖS »

@Lvnt,
HDMI Lag konusunda çok bilgim yok. Biraz araştıralım. Ama bu projede kesin olan şey şu ki, eğer istediğim şekilde yapabilirsem, çevirici ekstra bir LAG oluşturmayacak. Zira framebuffer kullanmıyoruz.

Ama HDMI sinyal TV yada Monitöre girdikten sonra, içeride bir LAG oluşuyorsa bunun için yapılabilecek birşey yok. Yani hangi kaynağı bağlarsak bağlayalım aynı LAG gene oluşacaktır. Bunu TV yada monitörün ayıbı olarak nitelendirmek gerekir eüer gerçekten varsa.

EDIT: Biraz bakındım, tahmin ettiğim gibi TV lerin kendi içlerinde bir LAG leri oluyormuş. Bununla ilgili bir yazı linkte. Sanırım TV nin game modu varsa onu seçmek LAG'i azaltıyor.

http://www.techhive.com/article/183928/how_to_find_and_fix_input_lag_in_your_HDTV_or_monitor.html

@MeG,
Scanline yapabildikten sonra bunu yapmak çok kolay.
Teşekkürler öneri için...
« Son Düzenleme: Şubat 23, 2016, 19:55:46 ÖS Gönderen: delimawi » Logged

AmigaFUN
Üye4
***
Mesaj Sayısı: 1.061


MC68060 inside!


Üyelik Bilgileri
« Yanıtla #8 : Şubat 23, 2016, 22:28:24 ÖS »

C64 ün görüntü çıkışını sizin tasarlayacağınız cihazın input kabul edeceği bir sistem yerine,

doğrudan C64 içine gömülmüş bir çözüm olsa (Amiga scandoublerlar gibi mesela.)

ve hatta görüntünün üretildiği yongayı (C64 te böyle bir şey varsa) FPGA ya programlasınız çıkışını istediğiniz gibi dışarı aktarsanız?

Yani işi görüntünün oluşturulduğu yerde ve anda halletseniz daha iyi olmaz mı?
Logged

Amiga1200/Apollo1260@80MHz@105MIPS/RapidRoadUSB/IndiAGAmk2cr
Amiga500+/ACA500/ACA1221ec@42Mhz/IndivisionECS
Turbo Chameleon 64 w/Docking Station
RaspberryPi Zero/1B/2B/3B
Lattepanda 4/64GB
delimawi
Uzman
*****
Mesaj Sayısı: 1.580



Üyelik Bilgileri
« Yanıtla #9 : Şubat 23, 2016, 22:39:17 ÖS »

Evet, bunun ciddi zorlukları olsa da yapılabilir. Bu işlem için VIC-II cipinin urettigi goruntuyu data ve adres bus ı sniff ederek replike etmek gerekiyor. Bu işlem gene bir FPGA icerisinde VIC in bir kopyasini modelleyerek yapilabilir.

Ancak kötü haber bu zaten çoktan yapıldı. Kahkaha chameleon64 aslinda bu is icin yapilmis bir kartustu. Hatta daha sonra FPGA de bol bol yer kaldigi icin bambaska ozellikler de eklendi ve temelde cikis amacindan cok farkli bir yere geldi.
Logged

wizofwor
Genel Yönetici
*****
Mesaj Sayısı: 3.810


Gosub ile gidilen yerden goto ile dönen adam


Üyelik Bilgileri WWW
« Yanıtla #10 : Şubat 24, 2016, 00:17:31 ÖÖ »

@AmigaFun:

Bu tarif ettiğin şeyin yapılmışı Turbo Chameleon zaten. Daha doğrusu başlangıçta öyleydi. Scandoubler yapacağım diye işe başlayıp daha iyi görüntü için VIC'i komple FPGA'ya kopyalayalım derken komple sıfırdan C64 yaptılar.
Logged

AmigaFUN
Üye4
***
Mesaj Sayısı: 1.061


MC68060 inside!


Üyelik Bilgileri
« Yanıtla #11 : Şubat 24, 2016, 11:33:40 ÖÖ »

Harika! yapılmışı var yani

TC 'nin scandoubler kısmına kadar olan bölümünü hayata geçirilmesi yeterli yani.

Bu şekilde olması çıktı kalitesinin en üst düzeyde olmasını sağlayacaktır sanırım.

Sizce?
Logged

Amiga1200/Apollo1260@80MHz@105MIPS/RapidRoadUSB/IndiAGAmk2cr
Amiga500+/ACA500/ACA1221ec@42Mhz/IndivisionECS
Turbo Chameleon 64 w/Docking Station
RaspberryPi Zero/1B/2B/3B
Lattepanda 4/64GB
delimawi
Uzman
*****
Mesaj Sayısı: 1.580



Üyelik Bilgileri
« Yanıtla #12 : Şubat 24, 2016, 13:22:05 ÖS »

Evet ama o yöntem hem çok daha zor bir uğraş hem de donanım daha kallavi. Fiyat/Performans oranı ne olur bilemiyorum.
O yöntemde bana çekici gelmeyen bir diğer nokta da kartuş portunu dolduruyor olması.
Logged

AmigaFUN
Üye4
***
Mesaj Sayısı: 1.061


MC68060 inside!


Üyelik Bilgileri
« Yanıtla #13 : Şubat 24, 2016, 14:33:59 ÖS »

Anlıyorum.

TC gibi kartuş portunda takmaya mecbur muyuz? Amiga 'da ki uygulamalar gibi olsun görüntü yongasını sökelim onun yerine takalım yada üzerine tersten şapka gibi geçirelim olmaz mı?

Link verdiğim ürünün maliyetini referans alsanız. Bunun %50 sine bitmez mi?
https://farm8.staticflickr.com/7528/15655219214_674682f00e_o.jpg
Logged

Amiga1200/Apollo1260@80MHz@105MIPS/RapidRoadUSB/IndiAGAmk2cr
Amiga500+/ACA500/ACA1221ec@42Mhz/IndivisionECS
Turbo Chameleon 64 w/Docking Station
RaspberryPi Zero/1B/2B/3B
Lattepanda 4/64GB
delimawi
Uzman
*****
Mesaj Sayısı: 1.580



Üyelik Bilgileri
« Yanıtla #14 : Şubat 24, 2016, 15:15:40 ÖS »

FPGA Günlükleri - II

Merhaba, geçen yazıda projeyi tanımlamış ve bu sefer FPGA ile HDMI görüntü üretmeye çalışacağımızdan bahsetmiştik.

Detaya girmeden önce HDMI kablosunu ve bu görüntü aktarım sinyaline biraz inceleyelim.

HDMI kablosu içerisinde görüntü aktarımı ile ilgili olarak bizi ilgilendiren 4 dijital sinyal mevcut. Bunlardan biri pixelClock, diğer üç tanesi ise genel olarak red, green ve blue sinyallerini taşıyan hatlar. Bu hatların her biri bir çift tel ve çevresinde sarılı bir shield katmanından oluşuyor. Yani 4 ayrı sinyali gönderebilmek için FPGA üzerinde 8 pine ihtiyacımız olacak. Bu yöntemle sinyal taşınmasına differential signalling deniliyor. Çift olan hatlardan biri pozitif iken diğeri negatif seviyede oluyor. Özellikle "HDMI gibi" hızlı sinyal taşıyan hatlarda bu yöntem hattın gürültüye karşı daha korunaklı olmasını sağlıyor. Çok kabaca örneğin dışarıran etki edecek olan bir parazit hem pozitif hem de negatif olana "hatlar fiziksel olarak yan yana taşındığı için" aynı oranda etki edeceğinden, sonuçta hatlar arasındaki fark okunurken gürültünün etkisi teorik olarak sıfır oluyor.

Çok uzatmamaya gayret ederek devam ediyorum. Ellerimizi kirleteceğimizden bahsetmiştim. Hızlıca testlere başlayabilmek için bir HDMI kablosunu tam ortadan kesip, yukarıda sözünü ettiğim 4 çift hattı çıkartıp, kullanacağımız FPGA board üzerine takabilmek için dişi pin header bağlantısı yapıyoruz. Daha sonra karıştırmamak için hem polaritelerini hem de hangi sinyal olduklarını işaretlemekte yada renk kodlaması yapmakta yarar var.



Artık FPGA kısmına geçebiliriz. Daha önce CycloneII veya CycloneIV kullanacağımı söylemiştim. Zira elimde başka FPGA yok. Şimdilik daha mütevazi olan CycloneII ile başlıyorum. Eğer proje ilerleyince sıkışırsak değişiklik yaparız. Tam da bu noktada fpga4fun sitesindeki HDMI bölümünü okumanızı öneririm. Ben de FPGA kodu ile ilgili olarak bu siteden ilham aldım. Ayrıca görsel olarak HDMI ile ilgili bazı teknik detaylarda paylaşılmış durumda.

http://www.fpga4fun.com/HDMI.html

FPGA Programlarken kullanılan iki temel HDL dili var. Bunlar VHDL ve Verilog. Açıkçası ben tamamen kendi alışkanlıklarımdan ötürü Verilog kullanmayı tercih ediyorum. Daha kolayıma geliyor. Eğer yeni başlayacaksanız aşağıdaki linkleri okuyarak tercihinizi yapabilirsiniz. İki dilde de aynı şeyler yapılabiliyor. Yani fonksiyon olarak eşdeğer olduklarını söyleyebiliriz.

http://electronics.stackexchange.com/questions/16767/vhdl-or-verilog
http://electronicdesign.com/what-s-difference-between/what-s-difference-between-vhdl-verilog-and-systemverilog
http://www.eetimes.com/author.asp?doc_id=1283049

Yavaş yavaş artık programlama kısmına geçebiliriz. Öncelikle fpga4fun sitesindeki kodu inceliyoruz. Bire bir CycloneII için uygun olmadığından bazı yerlerin değiştirilmesi gerekecek. Ayrıca bu kod 640x480 @60Hz bir görüntü üretiyor. Bizim günün sonunda ihtiyacımız olan görüntü mutlak suretle 50Hz olmalı ki C64 ile senkron olabilelim. Şu an için benim hedeflediğim format 720x576p @50Hz. Bakalım bu formatta görüntü üretebilecek miyiz?

Bu noktadan sonrasında, fpga4fun'dan gerekli ilhamı aldığımızı varsayarak kendi yazmış olduğum Verilog kodunu açıklamaya başlıyorum.

Kod:
// ----------------------------------------------------------------------------
// HDMI64 - C64 Video HDMI Converter (with Scanline Effect)
// [url]www.commodore.gen.tr[/url] - delimawi'2016
// ----------------------------------------------------------------------------
// Project based on HDMI Sample Code from fpga4fun.com
// ----------------------------------------------------------------------------

module HDMI_Converter
(
input pixelClock, //  Incomming Video Pixel Clock
input pixelClockX10, //  HDMI Bit Clock (pixelClockx10)
input button, // Option Button Input
output [2:0] TMDSp, TMDSn, // HDMI Output Pins
output TMDSp_clock, TMDSn_clock
);

Burada bir module tanımı yaptık. pixelClock ve pixelClockX10 olarak iki tane clock girişimiz var. Şimdilik kullanılmayan bir button girişi ve HDMI kablosuna bağlayacağımız 4 adet sinyal çıkışımız mevcut.

HDMI sinyalinde, her bir R,G,B değeri 8 bit olmasına rağmen kablo üzerinde 10 bit olarak gönderilir. Kalan 2 bit içerisine bir takım kontrol bilgileri oluyor. İşte bu sebeple bir gerçek pixelClock sinyaline bir de bunun tam 10 katı olan bir ikinci clock sinyaline ihtiyaç duyuyoruz. 10 kat hızlı olan clock'un her peryodunda, R,G,B verisine ait olan bir biti sıra ile dışarıya vereceğiz. Input olarak tanımlanmış olan bu iki girişe, CycloneII içerisinde bulunan PLL modüllerini kullanarak 30MHz ve on katı olan 300MHz frekanslarında sinyal üreteceğiz. Proje tam olarak bittiğinde aslında bu sinyali C64'ten gelen video sinyalinden extract edip oluşturacağız ki tam senkronizasyon sağlanabilsin.

Kod:
// ----------------------------------------------
// Timing 720x576 @50 Hz
// pixelClock 30MHz
// ----------------------------------------------
`define DISPLAY_WIDTH 720
`define DISPLAY_HEIGHT 576
`define FULL_WIDTH 968
`define FULL_HEIGHT 625
`define H_FRONT_PORCH 40
`define H_SYNC 72
`define V_FRONT_PORCH 3
`define V_SYNC 28

`define H_SYNC_BEGIN `DISPLAY_WIDTH+`H_FRONT_PORCH
`define H_SYNC_END `H_SYNC_BEGIN+`H_SYNC
`define V_SYNC_BEGIN `DISPLAY_HEIGHT+`V_FRONT_PORCH
`define V_SYNC_END `V_SYNC_BEGIN+`V_SYNC

Burada hazırlık olarak bazı tanımlamalar yaptık. Dikkat edilmesi gereken nokta 720x576 çözünürlüğünde bir video sinyali gönderdiğimiz halde aslında gerçekte 968x625 çözünürlüğünde bir data gidiyor. Bu ekran dışında kalan data içerisine bazı başka bilgiler de encode edilebiliyor. Örneğin ses. Bu arada tanımlanmış olan değerler tabiki içimize malum olmadı, internetten araştırıp bulduk. Örnek olarak aşağıdaki linkte bazı timing değerleri var.

http://tinyvga.com/vga-timing

Kod:
reg [9:0] counterX, counterY; // 10 Bit X,Y Counters (0-1023)
reg hSync,vSync; // HDMI Synch Pulses
reg drawArea; // Drawing Area Flag

always @(posedge pixelClock)
begin
drawArea<=(counterX<`DISPLAY_WIDTH)&&(counterY<`DISPLAY_HEIGHT);
hSync <= (counterX>=`H_SYNC_BEGIN)&&(counterX<`H_SYNC_END);
vSync <= (counterY>=`V_SYNC_BEGIN) && (counterY<`V_SYNC_END);
end

always @(posedge pixelClock)
begin
if (counterX==(`FULL_WIDTH-1))
begin
if (counterY==(`FULL_HEIGHT-1))
begin
counterY<=0;
end else
begin
counterY<=counterY+1;
end
counterX<=0;
end else
begin
counterX<=counterX+1;
end
end

counterX ve counterY registerlerini tanımladık ve saydırdık. Bunlar o an göndermekte olduğumuz X piksel pozisyonu ve satır numarasını taşıyan 10 bitlik değişkenler. Ayrıca yukarıda tanımlanan senkron timinglerine uygun olarak hSync ve vSync darbelerini de üretiyoruz. Son olarak drawArea registeri, o an göndermekte olduğumuz pikselin görünür alanda mı yoksa data bölgesinde mi olduğu gösteriyor.

Hazırlıklarımız yaptık, artık örnek bir pattern üretmeye çalışabiliriz.

Kod:
// ----------------------------------------------------------------------------
// Test Pattern Generator
// ----------------------------------------------------------------------------

reg [23:0] outColor;
reg [23:0] backColor;
reg [7:0] red, green, blue;
reg [7:0] redo, greeno, blueo;

always @(posedge pixelClock)
begin
// Temsili bir C64 bordur görüntüsü yaratalım ...
backColor=24'h446699;
if ((counterX>80) && (counterX<640) && (counterY>88) && (counterY<488)) backColor=24'h223377;

// C64 Renk Paletini temsili olarak yerleştirelim ...
outColor=backColor;

if ((counterY>150) && (counterY<200-10))
begin
if ((counterX>100) && (counterX<150-10)) outColor=24'h000000;
else if ((counterX>150) && (counterX<200-10)) outColor=24'hFFFFFF;
else if ((counterX>200) && (counterX<250-10)) outColor=24'h880000;
else if ((counterX>250) && (counterX<300-10)) outColor=24'hAAFFEE;
else if ((counterX>300) && (counterX<350-10)) outColor=24'hCC44CC;
else if ((counterX>350) && (counterX<400-10)) outColor=24'h00CC55;
else if ((counterX>400) && (counterX<450-10)) outColor=24'h0000AA;
else if ((counterX>450) && (counterX<500-10)) outColor=24'hEEEE77;
end

if ((counterY>200) && (counterY<250-10))
begin
if ((counterX>100) && (counterX<150-10)) outColor=24'hDD8855;
else if ((counterX>150) && (counterX<200-10)) outColor=24'h664400;
else if ((counterX>200) && (counterX<250-10)) outColor=24'hFF7777;
else if ((counterX>250) && (counterX<300-10)) outColor=24'h333333;
else if ((counterX>300) && (counterX<350-10)) outColor=24'h777777;
else if ((counterX>350) && (counterX<400-10)) outColor=24'hAAFF66;
else if ((counterX>400) && (counterX<450-10)) outColor=24'h0088FF;
else if ((counterX>450) && (counterX<500-10)) outColor=24'hBBBBBB;
end;

redo   <= outColor[23:16];
greeno <= outColor[15:8];
blueo  <= outColor[7:0];

// ----------------------------------------------------------------------------
// Scanline Effect
// ----------------------------------------------------------------------------
if (counterY[0]==1)
begin
  red <= (redo>>2)*3;
  green <= (greeno>>2)*3;
  blue <= (blueo>>2)*3;
end
else
begin
red<=redo;
green<=greeno;
blue<=blueo;
end
end

Burada yapılan işlem temsili olarak bir C64 bordür görüntüsü yaratmak ve gene bu bordür içerisine C64 renk paletinde olan 16 adet rengi kutucuklar halinde çizdirmekten ibaret. Çok detaya girmek istemiyorum. Kodu okuyup merak ettiği biryer olanlar varsa mesaj atabilir. Ayrıca burada daha önce sözünü ettiğimiz çakma scanline effect'in ilk denemesi mevcut. Eğer tek numaralı bir satır çiziyorsak, hesapladığımız renk değerinin %25 düşüğünü çıkışa gönderiyoruz. 

Kodun geri kalanı aşağıda.

Kod:
// ----------------------------------------------------------------------------
// Generate TDMS Encoded 10 Bit Signals
// ----------------------------------------------------------------------------

wire [9:0] TMDS_red;
wire [9:0] TMDS_green;
wire [9:0] TMDS_blue;

TMDS_encoder encode_R( .clk(pixelClock), .VD(red  ), .CD(2'b00)        , .VDE(drawArea), .TMDS(TMDS_red)    );
TMDS_encoder encode_G( .clk(pixelClock), .VD(green), .CD(2'b00)        , .VDE(drawArea), .TMDS(TMDS_green)  );
TMDS_encoder encode_B( .clk(pixelClock), .VD(blue ), .CD({vSync,hSync}), .VDE(drawArea), .TMDS(TMDS_blue)   );

// ----------------------------------------------------------------------------
// Generate TDMS Clock
// ----------------------------------------------------------------------------

wire clk_TMDS=pixelClockX10;

// ----------------------------------------------------------------------------
// Generate TDMS Signals (Serialise)
// ----------------------------------------------------------------------------

reg [3:0] TMDS_mod10=0;  // modulus 10 counter
reg [9:0] TMDS_shift_red=0; // 10 Bit Shift Registers
reg [9:0] TMDS_shift_green=0; // 10 Bit Shift Registers
reg [9:0] TMDS_shift_blue=0; // 10 Bit Shift Registers

reg TMDS_shift_load=0;

always @(posedge clk_TMDS) TMDS_shift_load <= (TMDS_mod10==4'd9);

always @(posedge clk_TMDS)
begin
TMDS_shift_red  <= TMDS_shift_load ? TMDS_red   : TMDS_shift_red  [9:1];
TMDS_shift_green <= TMDS_shift_load ? TMDS_green : TMDS_shift_green[9:1];
TMDS_shift_blue <= TMDS_shift_load ? TMDS_blue  : TMDS_shift_blue [9:1];
TMDS_mod10 <= (TMDS_mod10==4'd9) ? 4'd0 : TMDS_mod10+4'd1;
end

assign TMDSp[2]    = TMDS_shift_red[0]  ;
assign TMDSp[1]    = TMDS_shift_green[0];
assign TMDSp[0]    = TMDS_shift_blue[0] ;
assign TMDSp_clock = pixelClock;

assign TMDSn[2] = !TMDSp[2];
assign TMDSn[1] = !TMDSp[1];
assign TMDSn[0] = !TMDSp[0];
assign TMDSn_clock = !TMDSp_clock;

Burada yapılan işlem ise, 8bit olan RGB değerlerini 10 bit shift registerlar içerisine alıp, her bir bitClock'ta bir bitini dışarıya, HDMI kablosuna göndermek. Ayrıca fpga4fun sitesindeki kodun CycloneII ye tam uygun olmadığını söylemiştim. Burada o kısımların nasıl uyumlu hale getirildiği, sinyalin positive ve negative çiftler haline nasıl gönderildiği görülebilir.

Tüm bugları sıra ile giderdikten sonra sonucu görmeye geldi sıra. CycloneII board üzerine HDMI kablomuzun montajını yapıp, FPGA'i programlıyoruz.



Ve sonuç...



Scanline effecti daha iyi görebilmek için bir yakın çekim:



Az geldi bu diyorsak, %25 yerine %50 karartmalı hali:




Evet artık FPGA ile 720x576p @50Hz görüntü üretebildik. Şimdi bunu bir kaç farklı marka ve model TV ile test etmek gerekiyor. 720x576p @50Hz çok kullanılan bir format değil. 60Hz olanı kullanılıyor genelde. Eğer bir sıkıntı olmaz ise bundan sonrasında artık C64 tarafından gelen sinyali capture edip FPGA içerisine alma aşamaları var.

Şimdilik hoşçakalın...
Logged

Sayfa: [1] 2 3 ... 18   Yukarı git
Yazdır
Gitmek istediğiniz yer: