OpenCores
URL https://opencores.org/ocsvn/openfire2/openfire2/trunk

Subversion Repositories openfire2

[/] [openfire2/] [trunk/] [rtl/] [vga_controlador.v] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 toni32
/*      MODULE: openfire vga
2
        DESCRIPTION: Contains vga controller (displays pictures from RAM)
3
 
4
AUTHOR:
5
Antonio J. Anton
6
Anro Ingenieros (www.anro-ingenieros.com)
7
aj@anro-ingenieros.com
8
 
9
REVISION HISTORY:
10
Revision 1.0, 26/03/2007
11
Initial release
12
 
13
COPYRIGHT:
14
Copyright (c) 2007 Antonio J. Anton
15
 
16
Permission is hereby granted, free of charge, to any person obtaining a copy of
17
this software and associated documentation files (the "Software"), to deal in
18
the Software without restriction, including without limitation the rights to
19
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
20
of the Software, and to permit persons to whom the Software is furnished to do
21
so, subject to the following conditions:
22
 
23
The above copyright notice and this permission notice shall be included in all
24
copies or substantial portions of the Software.
25
 
26
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
SOFTWARE.*/
33
 
34
`timescale 1ns / 1ps
35
`include "openfire_define.v"
36
 
37
//***************************************************************************
38
// VGA timming by Jason Stewart
39
// http://www.cs.unc.edu/~stewart/comp290-ghw/vga.html
40
//
41
// Filename:  vga_controller.v
42
//
43
// Module for a simple vga controller. A "horizontal counter" counts pixels 
44
// in a line, including the sync pulse, front porch, back porch, etc. Then, 
45
// a "pulse generator" looks at the output of the counter and outputs a 
46
// pulse of a given length starting at a given count. These are used to 
47
// generate the sync pulse and the active video signal. Parameters for 
48
// the counter and pulse generators appear below.
49
//
50
// The logic for vertical is similar. The main difference is that the 
51
// vertical counter has a clock enable, which is used to make the vert 
52
// counter count lines instead of pixels. Specifically, the hsync from 
53
// the horizontal stage (which occurs once per line) creates a 1-cycle 
54
// pulse for the vert counter clock enable, and thus the vert counter 
55
// increments on every hsync.
56
//
57
// In general, you can play around with the start counts for the sync pulse 
58
// and active signal. This basically increases/decreases the front and back 
59
// porches, thereby moving the frame up/down or left/right on the screen.
60
//***************************************************************************
61
module vga_controller(cpu_clk, pixel_clk, reset,
62
                                                         hsync_n, vsync_n, red, green, blue,
63
                                                         ram_pointer, ram_data, req, rdy);
64
 
65
// The default parameters are for 800x600 @ 72 Hz (assuming a 50 MHz clock). 
66
/*  parameter N1       = 11;    // number of counter bits  HORIZONTAL
67
  parameter HCOUNT   = 1040;  // total pixel count
68
  parameter HS_START = 40;    // start of hsync pulse
69
  parameter HS_LEN   = 120;   // length of hsync pulse
70
  parameter HA_START = 224;   // start of active video
71
  parameter HA_LEN   = 800;   // length of active video
72
 
73
  parameter N2 = 10;          // number of counter bits  VERTICAL
74
  parameter VCOUNT = 666;     // total line count
75
  parameter VS_START = 24;    // start of vsync pulse
76
  parameter VS_LEN   = 6;     // length of vsync pulse
77
  parameter VA_START = 64;    // start of active video
78
  parameter VA_LEN   = 600;   // length of active video */
79
 
80
// For 640x480 @ 60 Hz, use the following (assuming a 25 MHz clock):
81
  parameter N1       = 10;
82
  parameter HCOUNT   = 800;
83
  parameter HS_START = 8;
84
  parameter HS_LEN   = 96;
85
  parameter HA_START = 127;
86
  parameter HA_LEN   = 640;
87
 
88
  parameter N2 = 10;
89
  parameter VCOUNT = 525;
90
  parameter VS_START = 2;
91
  parameter VS_LEN   = 2;
92
  parameter VA_START = 24;
93
  parameter VA_LEN   = 480;
94
 
95
  input  cpu_clk;                               // clock de la cpu
96
  input  pixel_clk;                     // pixel clock
97
  input reset;
98
  output hsync_n, vsync_n;      // seņales sincronismo
99
  output red;                                   // color
100
  output green;
101
  output blue;
102
 
103
  output [17:0]  ram_pointer;    // SRAM pointer (32 bit aligned)
104
  input [31:0]   ram_data;               // data from SRAM
105
  output req;                                                   // read request
106
  input  rdy;                                                   // SRAM data available
107
 
108
  wire hsync, vsync;                                    // --- sync signals are negated ----
109
  wire hsync_n = ~hsync;
110
  wire vsync_n = ~vsync;
111
 
112
  wire htc, vtc, vce;                           // --------- Sync pulse stuff ----------  
113
  wire hactive, vactive;
114
  wire [N1-1:0] hcnt;
115
  wire [N2-1:0] vcnt;
116
 
117
  // horizontal
118
  counter_tc #(N1,HCOUNT)                 H_CNT(pixel_clk, reset, hcnt, htc);
119
  pulse_gen #(N1,HS_START,HS_LEN)  H_SYNC(pixel_clk, reset, hcnt, hsync);
120
  pulse_gen #(N1,HA_START,HA_LEN)  H_ACTIVE(pixel_clk, reset, hcnt, hactive);
121
 
122
  // vertical
123
  pulse_high_low                   V_CNT_CE(pixel_clk, reset, hsync, vce);
124
  counter_tc_ce #(N2,VCOUNT)         V_CNT(pixel_clk, reset, vce, vcnt, vtc);
125
  pulse_gen #(N2,VS_START,VS_LEN)  V_SYNC(pixel_clk, reset, vcnt, vsync);
126
  pulse_gen #(N2,VA_START,VA_LEN)  V_ACTIVE(pixel_clk, reset, vcnt, vactive);
127
 
128
// -------- memory and video parameters ------------
129
  reg [17:0] ram_pointer;                // memory pointer
130
  reg            req;                                   // indica si hay que leer desde memoria
131
 
132
  wire red;                                                     // output RGB signals (1 bpp)
133
  wire green;
134
  wire blue;
135
 
136
  reg   [9:0]    pixels_red;                     // WORD = x RGB RGB RGB RGB RGB x RGB RGB RGB RGB RGB
137
  reg   [9:0] pixels_green;              //               1 098 765 432 109 876 5 432 109 876 543 210
138
  reg [9:0] pixels_blue;                 //                         3            2             1
139
  reg [3:0]      contador_pixels;        // pixel counter
140
  reg      leer;                                        // video asks SRAM reader next word
141
  reg                   leido;                          // SRAM reader notifies video the data is available
142
 
143
assign red   = (hactive && vactive) && pixels_red[9];                   // current pixel 
144
assign green = (hactive && vactive) && pixels_green[9];
145
assign blue  = (hactive && vactive) && pixels_blue[9];
146
 
147
// --------- retrieve 1 word (30 pixels) each time from SRAM  ---------
148
always @(posedge cpu_clk)
149
begin
150
 if(reset || !vactive)                                          // reset or vertical retrace -> restart
151
 begin
152
  ram_pointer <= `LOCATION_VRAM;                        // video memory at the end of the SRAM (upper 120 Kbytes)
153
  req             <= 0;
154
  leido                   <= 0;
155
 end
156
 else
157
 begin
158
  if(!leido && leer && !req)                            // request data
159
  begin
160
         req <= 1;
161
  end
162
  else if(!leido && leer && req && rdy)// data avaiable (registered at controller level)
163
  begin
164
         req      <= 0;
165
         leido    <= 1;
166
  end
167
  else if(leido && !leer)                                       // waiting next read
168
  begin
169
    leido <= 0;
170
         ram_pointer <= ram_pointer + 1;
171
  end
172
 end
173
end
174
 
175
// ------- pintamos los pixels (al pixel clock) --------
176
wire first_pixel                = (contador_pixels == 0);
177
wire threshold_pixel = (contador_pixels == 2);
178
wire last_pixel         = (contador_pixels == 9);
179
 
180
always @(posedge pixel_clk)
181
begin
182
 if(reset)                                                      // tras un reset -> pedir el 1er word a SRAM
183
 begin
184
   leer                                         <= 1;           // on startup request next data
185
   contador_pixels      <= 0;
186
   pixels_red                   <= 10'b0;
187
   pixels_green                 <= 10'b0;
188
   pixels_blue                  <= 10'b0;
189
 end
190
 else if(hactive && vactive)    // we are in visible area
191
 begin
192
        pixels_red       <= first_pixel ? { ram_data[30], ram_data[27], ram_data[24], ram_data[21], ram_data[18], ram_data[14], ram_data[11], ram_data[8], ram_data[5], ram_data[2] } : { pixels_red[8:0],       1'bX };
193
        pixels_green <= first_pixel ? { ram_data[29], ram_data[26], ram_data[23], ram_data[20], ram_data[17], ram_data[13], ram_data[10], ram_data[7], ram_data[4], ram_data[1] } : { pixels_green[8:0], 1'bX };
194
        pixels_blue  <= first_pixel ? { ram_data[28], ram_data[25], ram_data[22], ram_data[19], ram_data[16], ram_data[12], ram_data[9],  ram_data[6], ram_data[3], ram_data[0] } : { pixels_blue[8:0],   1'bX };
195
        if(threshold_pixel) leer <= 1;          // fetch next word before current is processed
196
        else if(leido)    leer <= 0;             // if already done, release flag
197
        contador_pixels <= last_pixel ? 0 : contador_pixels + 1;         // pixel counter
198
 end
199
end
200
 
201
endmodule
202
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.