Son olarak aşağıda FPGA Verilog dosyasının son hali mevcut. Gerekli açıklamaları ekledim ve düzenledim.
Upload ederken hata verdiği için parça parça ekledim.
// ----------------------------------------------------------------------------
// VGA Encoder Module
// [url]www.commodore.gen.tr[/url] - delimawi'2016
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// VGA-16 IDC Input Pins
// ----------------------------------------------------------------------------
// 1 2.2 K R1 112
// 2 3.9 K R0 113
// 3 1.0 K R2 114
// 4 0.47 K R3 115
// 5 3.9 K G0 118
// 6 0.22 K R4 120
// 7 3.9 K B0 121
// 8 2.2 K B1 122
// 9 0.22 K G4 125
// 10 0.47 K G3 126
// 11 1.0 K G2 133
// 12 1.0 K B2 134
// 13 0.47 K B3 135
// 14 2.2 K G1 137
// 15 0.22 K B4 139
// 16 Frame Sync Input
// 17 GND
// 18 12MHz NEO GEO Clock Input
// 19 GND
// 20 VCC (+5V) Input
// ----------------------------------------------------------------------------
module VGA_Encoder
(
// RGB Video Input 3x5=15Bit
input [4:0] InputRed,
input [4:0] InputGreen,
input [4:0] InputBlue,
// RGB Video Frame Sync Signal
input SyncIn,
// 24MHz Video Clock Input from PLL (Normalde VGA 25MHz... :)
input VGA_Clock,
// 6 MHz RGB Sampler Clock (Output, generated internally)
output RGB_Clock,
// Scanline Buffer RAM Write
output reg [9:0] RamWrAddr,
output [15:0] RamWrData,
// Scanline Buffer RAM Read
output [9:0] RamRdAddr,
input [15:0] RamRdData,
// Config Bits
input [4:0] Config,
// Analog VGA Output
output reg [4:0] VGA_Red,
output reg [4:0] VGA_Green,
output reg [4:0] VGA_Blue,
// VGA Sync Pulses
output reg VGA_H_Sync,
output reg VGA_V_Sync
);
// ----------------------------------------------------------------------------
// Neo Geo RGB Video Input
// ----------------------------------------------------------------------------
// 6 MHz Pixel Clock
// 384 Pixels/Line
// 264 Lines/Frame
// 59.1856 Frames/Second
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// VGA Output Timing (MODIFIED !!!)
// ----------------------------------------------------------------------------
`define DISPLAY_WIDTH 640
`define DISPLAY_HEIGHT 480
`define FULL_WIDTH 768 // Normalde 800
`define FULL_HEIGHT 528 // Normalde 525
`define H_FRONT_PORCH 12 // Normalde 16
`define H_SYNC 96
`define V_FRONT_PORCH 12 // 10
`define V_SYNC 2
Senkron üreteci:
// ----------------------------------------------------------------------------
// Frame SyncPulse Generator
// ----------------------------------------------------------------------------
// Frame Senkron işareti geldiği anda pulse üretiyor.
// ----------------------------------------------------------------------------
reg PrevSyncIn;
assign SynchPulse=((SyncIn==1)&&(PrevSyncIn==0));
always @(posedge VGA_Clock)
begin
if (RGB_ClockPhase==0) PrevSyncIn<=SyncIn;
end
Neo Geo RGB Sinyalini örnekleyip RAM'e atan kısım:
// ----------------------------------------------------------------------------
// 6MHz RGB Sampler Clock Generator
// ----------------------------------------------------------------------------
// 24MHz VGA Clock'u 4'e bolerek 6MHz uretecegiz
// Ancak bu RGB Sampler Clock, Gelen Synch işareti ile senkron olmalı !
// Senkron işaretini görünce RGB_ClockPhase registerini resetleyelim.
// ----------------------------------------------------------------------------
reg [1:0] RGB_ClockPhase;
assign RGB_Clock=(RGB_ClockPhase==0);
always @(posedge VGA_Clock)
begin
if (SynchPulse) RGB_ClockPhase[1:0]<=0; else RGB_ClockPhase[1:0]<=RGB_ClockPhase[1:0]+1;
end
// ----------------------------------------------------------------------------
// RGB Sampler (@6MHz)
// ----------------------------------------------------------------------------
// Route NeoGeo Video Data to FIFO RAM Directly.
// RamWrAddr will be calculated.
// ----------------------------------------------------------------------------
assign RamWrData[4:0] = InputRed[4:0];
assign RamWrData[9:5] = InputGreen[4:0];
assign RamWrData[14:10] = InputBlue[4:0];
reg [8:0] RGB_LineNo;
always @(posedge RGB_Clock)
begin
//if (RGB_ClockPhase==0)
//begin
// Eğer senkron işareti geldiyse RAM yazma adresini resetle, aksi halde adresi arttıralım.
if (SynchPulse) RamWrAddr<=0; else RamWrAddr<=RamWrAddr+1;
// Satırın tam ortasında biryerlerdeyken Sync işaretini kontrol et.
// Sync gelmiş ise Frame başındayız demektir. RGB_LineNo'yu resetle ...
if (RamWrAddr==182)
begin
if (SyncIn==1) RGB_LineNo<=0; else RGB_LineNo<=RGB_LineNo+1;
end;
//end;
end
VGA Sinyalini Üreten kısım:
// ----------------------------------------------------------------------------
// 640x480 - VGA Signal Generator
// ----------------------------------------------------------------------------
reg [9:0] VGA_X_Pos, VGA_Y_Pos;
assign RamRdAddr=VGA_X_Pos>>1;
always @(posedge VGA_Clock)
begin
if (VGA_X_Pos==(`FULL_WIDTH-1))
begin
VGA_X_Pos<=0;
// 12. RGB Satırında VGA Y Reset edelim.
// (Front Porch vb. sebebi ile düşey senkron tutturmak için)
if (RGB_LineNo==12) VGA_Y_Pos<=0; else VGA_Y_Pos<=VGA_Y_Pos+1;
end else
begin
// Senkron geldiği anda, eğer VGA yatay tarama yanlış bir yerde ise onu da senkron et...
if ((SynchPulse) && (VGA_X_Pos>5)) VGA_X_Pos<=0; else VGA_X_Pos<=VGA_X_Pos+1;
end
VGA_H_Sync <= !( (VGA_X_Pos>=(`DISPLAY_WIDTH +`H_FRONT_PORCH )) && (VGA_X_Pos<(`DISPLAY_WIDTH +`H_FRONT_PORCH +`H_SYNC )) );
VGA_V_Sync <= !( (VGA_Y_Pos>=(`DISPLAY_HEIGHT +`V_FRONT_PORCH )) && (VGA_Y_Pos<(`DISPLAY_HEIGHT +`V_FRONT_PORCH +`V_SYNC )) );
end
Yatay pixel blur effekti:
// ----------------------------------------------------------------------------
// Horizontal Pixel Blur Effect
// ----------------------------------------------------------------------------
// Arka arkaya gelen son iki pixel'i hafızada tutuyoruz,
// İstenilen oranda ortalama alıyoruz.
// Sonuçlar, Reg, Green, Blue registerlarında. (Her biri 8 Bit)
// ----------------------------------------------------------------------------
reg [4:0] pR0, pG0, pB0;
reg [4:0] pR1, pG1, pB1;
reg [7:0] Red, Green, Blue;
always @(posedge VGA_Clock)
begin
// Yataydaki son 2 pikseli hafızada tut
pR1[4:0]<=pR0[4:0];
pG1[4:0]<=pG0[4:0];
pB1[4:0]<=pG0[4:0];
pR0[4:0]<=RamRdData[4:0];
pG0[4:0]<=RamRdData[9:5];
pB0[4:0]<=RamRdData[14:10];
// 0-Blur None
if (Config[3:2]==3)
begin
Red[7:0]= RamRdData[4:0]*8;
Green[7:0]= RamRdData[9:5]*8;
Blue[7:0]= RamRdData[14:10]*8;
end
// 1-Blur Low
else if (Config[3:2]==2)
begin
Red[7:0]= (pR0[4:0]+RamRdData[4:0]+RamRdData[4:0]+RamRdData[4:0])*2;
Green[7:0]= (pG0[4:0]+RamRdData[9:5]+RamRdData[9:5]+RamRdData[9:5])*2;
Blue[7:0]= (pB0[4:0]+RamRdData[14:10]+RamRdData[14:10]+RamRdData[14:10])*2;
end
// 2-Blur Mid
else if (Config[3:2]==1)
begin
Red[7:0]= (pR0[4:0]+pR0[4:0]+RamRdData[4:0]+RamRdData[4:0])*2;
Green[7:0]= (pG0[4:0]+pG0[4:0]+RamRdData[9:5]+RamRdData[9:5])*2;
Blue[7:0]= (pB0[4:0]+pB0[4:0]+RamRdData[14:10]+RamRdData[14:10])*2;
end
// 3-Blur High
else
begin
Red[7:0]= (pR0[4:0]+pR1[4:0]+RamRdData[4:0]+RamRdData[4:0])*2;
Green[7:0]= (pG0[4:0]+pG1[4:0]+RamRdData[9:5]+RamRdData[9:5])*2;
Blue[7:0]= (pB0[4:0]+pB1[4:0]+RamRdData[14:10]+RamRdData[14:10])*2;
end
end
Scanline generator:
// ----------------------------------------------------------------------------
// Scanline Effect & Output Blanking ...
// ----------------------------------------------------------------------------
wire [9:0] ColorPos;
assign ColorPos=VGA_X_Pos-39-30;
always @(posedge VGA_Clock)
begin
//ColorPos<=VGA_X_Pos-39;
// Draw Frame VGA MAX (TEST)
if (((VGA_X_Pos==22) || (VGA_X_Pos==636) || (VGA_Y_Pos==0) || (VGA_Y_Pos==479)) && (Config[4]==0))
begin
VGA_Red[4:0]<=31;
VGA_Green[4:0]<=31;
VGA_Blue[4:0]<=31;
end else
// Draw Frame NEO GEO NOMINAL (TEST)
if (((VGA_X_Pos==36) || (VGA_X_Pos==615) || (VGA_Y_Pos==12) || (VGA_Y_Pos==461)) && (Config[4]==0))
begin
VGA_Red[4:0]<=0;
VGA_Green[4:0]<=31;
VGA_Blue[4:0]<=0;
end else
// Color Bars TOP...
if ((VGA_Y_Pos<11) && (VGA_Y_Pos>1) && (VGA_X_Pos>38+30) && (Config[4]==0))
begin
if (ColorPos[3:0]==0)
begin
VGA_Red[4:0]<=0;
VGA_Green[4:0]<=0;
VGA_Blue[4:0]<=0;
end else
begin
VGA_Red[4:0]<=ColorPos[8:4];
VGA_Green[4:0]<=ColorPos[8:4];
VGA_Blue[4:0]<=ColorPos[8:4];
end;
end else
// Color Bars BOTTOM...
if ((VGA_Y_Pos<475) && (VGA_Y_Pos>465) && (VGA_X_Pos>38+30) && (Config[4]==0))
begin
if (ColorPos[9:7]==0)
begin
VGA_Red[4:0]<=ColorPos[6:2];
VGA_Green[4:0]<=0;
VGA_Blue[4:0]<=0;
end else
if (ColorPos[9:7]==1)
begin
VGA_Red[4:0]<=0;
VGA_Green[4:0]<=ColorPos[6:2];
VGA_Blue[4:0]<=0;
end else
if (ColorPos[9:7]==2)
begin
VGA_Red[4:0]<=0;
VGA_Green[4:0]<=0;
VGA_Blue[4:0]<=ColorPos[6:2];
end else
if (ColorPos[9:7]==3)
begin
VGA_Red[4:0]<=ColorPos[6:2];
VGA_Green[4:0]<=ColorPos[6:2];
VGA_Blue[4:0]<=ColorPos[6:2];
end else
begin
VGA_Red[4:0]<=0;
VGA_Green[4:0]<=0;
VGA_Blue[4:0]<=0;
end;
end else
// --------------------------------------------------------------------------------
// Draw Limits (Blanking) ...
// --------------------------------------------------------------------------------
if ((VGA_X_Pos<22) || (VGA_X_Pos>636) || (VGA_Y_Pos<10) || (VGA_Y_Pos>460))
begin
VGA_Red[4:0]<=0;
VGA_Green[4:0]<=0;
VGA_Blue[4:0]<=0;
end else
// --------------------------------------------------------------------------------
// Scanline Generator (Dimmed Lines)
// --------------------------------------------------------------------------------
if (VGA_Y_Pos[0]==0)
begin
if (Config[1:0]==3)
begin
VGA_Red[4:0]<=Red/8;
VGA_Green[4:0]<=Green/8;
VGA_Blue[4:0]<=Blue/8;
end
else if (Config[1:0]==2)
begin
VGA_Red[4:0]<=Red/16;
VGA_Green[4:0]<=Green/16;
VGA_Blue[4:0]<=Blue/16;
end
else if (Config[1:0]==1)
begin
VGA_Red[4:0]<=Red/32;
VGA_Green[4:0]<=Green/32;
VGA_Blue[4:0]<=Blue/32;
end else
begin
VGA_Red[4:0]<=0;
VGA_Green[4:0]<=0;
VGA_Blue[4:0]<=0;
end
// --------------------------------------------------------------------------------
// Scanline Generator (Normal Lines)
// --------------------------------------------------------------------------------
end else
begin
VGA_Red[4:0]<=Red/8;
VGA_Green[4:0]<=Green/8;
VGA_Blue[4:0]<=Blue/8;
end;
end
endmodule
Kart üzerinde 5 adet config jumper var.
1 ve 2 numaralı olanlar scanline miktarını
3 ve 4 numaralı olanlar yataydaki pixel blur miktarını
5 numaralı olan ise test pattern gösterimi için kullanılıyor.
Sevgiler, Saygılar ...