module vga(clk,hsync,vsync,rgb,irq_60Hz,irq_clear,mwe,maddr,mdin,mdout,blank,
pixel_clk);
input clk; // 50Mhz
output hsync;
output vsync;
output [2:0] rgb;
output irq_60Hz;
input irq_clear;
output blank;
output pixel_clk;
input mwe;
input [9:0] maddr; // access to character buffer
input [31:0] mdin;
output [31:0] mdout;
// pixel clock: 25Mhz = 40ns (clk/2)
reg pcount; // used to generate pixel clock
wire en = (pcount == 0);
always @ (posedge clk) pcount <= ~pcount;
wire pixel_clk = ~en;
//****************************************************************
//****************************************************************
//***
//*** Sync and Blanking Signals
//***
//****************************************************************
//****************************************************************
reg irq_60Hz;
reg hsync,vsync,hblank,vblank;
reg [9:0] hcount; // pixel number on current line
reg [9:0] vcount; // line number
// horizontal: 794 pixels = 31.76us
// display 640 pixels per line
wire hsyncon,hsyncoff,hreset,hblankon;
assign hblankon = en & (hcount == 639);
assign hsyncon = en & (hcount == 652);
assign hsyncoff = en & (hcount == 746);
assign hreset = en & (hcount == 793);
// vertical: 528 lines = 16.77us
// display 480 lines
wire vsyncon,vsyncoff,vreset,vblankon;
assign vblankon = hreset & (vcount == 479);
assign vsyncon = hreset & (vcount == 492);
assign vsyncoff = hreset & (vcount == 494);
assign vreset = hreset & (vcount == 527);
// sync and blanking
always @(posedge clk) begin
hcount <= en ? (hreset ? 0 : hcount + 1) : hcount;
hblank <= hreset ? 0 : hblankon ? 1 : hblank;
hsync <= hsyncon ? 0 : hsyncoff ? 1 : hsync; // hsync is active low
vcount <= hreset ? (vreset ? 0 : vcount + 1) : vcount;
vblank <= vreset ? 0 : vblankon ? 1 : vblank;
vsync <= vsyncon ? 0 : vsyncoff ? 1 : vsync; // vsync is active low
// 60Hz interrupt requested at start of vertical retrace.
// irq is reset by access to penultimate word in cmem
if (hreset && vreset) irq_60Hz <= 1;
else if (irq_clear) irq_60Hz <= 0;
end
wire blank = vblank | hblank;
//****************************************************************
//****************************************************************
//***
//*** 80 x 40 character display (8 x 12 characters)
//***
//****************************************************************
//****************************************************************
reg [6:0] column; // 0 .. 79
reg [5:0] row; // 0 .. 39
reg [3:0] v; // 0 .. 11
reg [2:0] h; // 0 .. 7
wire [6:0] next_column = hreset ? 0 :
h == 7 ? column+1 :
column;
wire [5:0] next_row = hreset ? (vreset ? 0 : (v == 11) ? row+1 : row) : row;
always @ (posedge clk)
if (en) begin
h <= hreset ? 0 : h+1;
if (hreset) v <= (vreset || v == 11) ? 0 : v+1;
column <= next_column;
row <= next_row;
end
// look up character in 80x40 buffer. Use next_row and next_column
// so that synchronous memory can get started at beginning of pixel
wire [11:0] char_addr = next_row*80 + next_column;
wire [7:0] char;
xcmem b(.addra(char_addr),.clka(clk),.douta(char),
.addrb(maddr),.clkb(clk),.dinb(mdin),.doutb(mdout),.web(mwe));
// look up raster row from font rom. Since we're using the 2x clock
// this will happen halfway thru the pixel and the raster data can
// be latched at the beginning of the next pixel.
reg reverse;
always @ (posedge clk) reverse <= char[7];
wire [10:0] font_addr = char[6:0]*12 + v; // 12 bytes per character
wire [7:0] font_byte;
xfont f(font_addr,clk,font_byte);
wire [2:0] f_pixel = (font_byte[7 - h] ^ reverse) ? 7 : 0;
//****************************************************************
//****************************************************************
//***
//*** Pixel logic
//***
//****************************************************************
//****************************************************************
wire [2:0] borderpix = (hcount==0|hcount==639|vcount==0|vcount==479) ? 7:0;
reg [2:0] rgb;
always @(posedge clk) if (en) begin
// if (vblank | (hblank & ~hreset)) // blanking => black
// rgb <= 0;
// else
rgb <= f_pixel | borderpix;
end
endmodule
This page: |
Created: | Thu Dec 8 21:44:34 2005 |
|
From: |
./vga.v |