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

Subversion Repositories vga_lcd

[/] [vga_lcd/] [tags/] [rel_1/] [rtl/] [verilog/] [vga_curproc.v] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 31 rherveille
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  WISHBONE rev.B2 compliant enhanced VGA/LCD Core            ////
4
////  Hardware Cursor Processor                                  ////
5
////                                                             ////
6
////  Author: Richard Herveille                                  ////
7
////          richard@asics.ws                                   ////
8
////          www.asics.ws                                       ////
9
////                                                             ////
10
////  Downloaded from: http://www.opencores.org/projects/vga_lcd ////
11
////                                                             ////
12
/////////////////////////////////////////////////////////////////////
13
////                                                             ////
14
//// Copyright (C) 2002 Richard Herveille                        ////
15
////                    richard@asics.ws                         ////
16
////                                                             ////
17
//// This source file may be used and distributed without        ////
18
//// restriction provided that this copyright statement is not   ////
19
//// removed from the file and that any derivative work contains ////
20
//// the original copyright notice and the associated disclaimer.////
21
////                                                             ////
22
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
23
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
24
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
25
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
26
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
27
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
28
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
29
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
30
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
31
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
32
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
33
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
34
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
35
////                                                             ////
36
/////////////////////////////////////////////////////////////////////
37
 
38
//  CVS Log
39
//
40 34 rherveille
//  $Id: vga_curproc.v,v 1.3 2002-03-04 16:05:52 rherveille Exp $
41 31 rherveille
//
42 34 rherveille
//  $Date: 2002-03-04 16:05:52 $
43
//  $Revision: 1.3 $
44 31 rherveille
//  $Author: rherveille $
45
//  $Locker:  $
46
//  $State: Exp $
47
//
48
// Change History:
49
//               $Log: not supported by cvs2svn $
50 34 rherveille
//               Revision 1.2  2002/03/04 11:01:59  rherveille
51
//               Added 64x64pixels 4bpp hardware cursor support.
52
//
53 33 rherveille
//               Revision 1.1  2002/02/16 10:40:00  rherveille
54
//               Some minor bug-fixes.
55
//               Changed vga_ssel into vga_curproc (cursor processor).
56
//
57 31 rherveille
//               Revision 1.1  2002/02/07 05:42:10  rherveille
58
//               Fixed some bugs discovered by modified testbench
59
//               Removed / Changed some strange logic constructions
60
//               Started work on hardware cursor support (not finished yet)
61
//               Changed top-level name to vga_enh_top.v
62
//
63
 
64
`include "timescale.v"
65
 
66
module vga_curproc (clk, rst_i, Thgate, Tvgate, idat, idat_wreq,
67 33 rherveille
        cursor_xy, cursor_en, cursor_res,
68
        cursor_wadr, cursor_wdat, cursor_we,
69
        cc_adr_o, cc_dat_i,
70 31 rherveille
        rgb_fifo_wreq, rgb);
71
 
72
        //
73
        // inputs & outputs
74
        //
75
 
76
        // wishbone signals
77
        input         clk;           // master clock input
78
        input         rst_i;         // synchronous active high reset
79
 
80
        // image size
81
        input [15:0] Thgate, Tvgate; // horizontal/vertical gate
82
        // image data
83
        input [23:0] idat;           // image data input
84
        input        idat_wreq;      // image data write request
85
 
86
        // cursor data
87
        input [31:0] cursor_xy;      // cursor (x,y)
88
        input        cursor_en;      // cursor enable (on/off)
89 33 rherveille
        input        cursor_res;     // cursor resolution (32x32 or 64x64 pixels)
90
        input [ 8:0] cursor_wadr;    // cursor buffer write address
91
        input [31:0] cursor_wdat;    // cursor buffer write data
92
        input        cursor_we;      // cursor buffer write enable
93 31 rherveille
 
94 33 rherveille
        // color registers interface
95
        output [ 3:0] cc_adr_o;      // cursor color registers address
96
        reg  [ 3:0] cc_adr_o;
97
        input  [15:0] cc_dat_i;      // cursor color registers data
98
 
99 31 rherveille
        // rgb-fifo connections
100
        output        rgb_fifo_wreq; // rgb-out write request
101
        reg        rgb_fifo_wreq;
102
        output [23:0] rgb;           // rgb data output
103
        reg [23:0] rgb;
104
 
105
        //
106
        // variable declarations
107
        //
108 33 rherveille
        reg         dcursor_en, ddcursor_en, dddcursor_en;
109 31 rherveille
        reg  [15:0] xcnt, ycnt;
110
        wire        xdone, ydone;
111
        wire [15:0] cursor_x, cursor_y;
112 34 rherveille
        wire        cursor_isalpha;
113
        reg  [15:0] cdat, dcdat;
114
        wire [ 7:0] cursor_r, cursor_g, cursor_b, cursor_alpha;
115 31 rherveille
        reg         inbox_x, inbox_y;
116
        wire        inbox;
117 33 rherveille
        reg         dinbox, ddinbox, dddinbox;
118 31 rherveille
 
119 33 rherveille
        reg  [23:0] didat, ddidat, dddidat;
120
        reg         didat_wreq, ddidat_wreq;
121
        wire [31:0] cbuf_q;
122
        reg  [11:0] cbuf_ra;
123
        reg  [ 2:0] dcbuf_ra;
124
        wire [ 8:0] cbuf_a;
125
 
126
        reg         store1, store2;
127
 
128 31 rherveille
        //
129
        // module body
130
        //
131
 
132 33 rherveille
        //
133 31 rherveille
        // generate x-y counters
134
        always@(posedge clk)
135
                if(rst_i || xdone)
136
                        xcnt <= #1 16'h0;
137
                else if (idat_wreq)
138
                        xcnt <= #1 xcnt + 16'h1;
139
 
140
        assign xdone = (xcnt == Thgate) && idat_wreq;
141
 
142
        always@(posedge clk)
143
                if(rst_i || ydone)
144
                        ycnt <= #1 16'h0;
145
                else if (xdone)
146
                        ycnt <= #1 ycnt + 16'h1;
147
 
148 33 rherveille
        assign ydone = (ycnt == Tvgate) && xdone;
149 31 rherveille
 
150
 
151
        // decode cursor (x,y)
152
        assign cursor_x = cursor_xy[15: 0];
153
        assign cursor_y = cursor_xy[31:16];
154
 
155 33 rherveille
        //
156 31 rherveille
        // generate inbox signals
157
        always@(posedge clk)
158
                begin
159 33 rherveille
                        inbox_x <= #1 (xcnt >= cursor_x) && (xcnt < (cursor_x + (cursor_res ? 16'h7f : 16'h1f) ));
160
                        inbox_y <= #1 (ycnt >= cursor_y) && (ycnt < (cursor_y + (cursor_res ? 16'h7f : 16'h1f) ));
161 31 rherveille
                end
162
 
163
        assign inbox = inbox_x && inbox_y;
164
 
165 33 rherveille
        always@(posedge clk)
166
                dinbox <= #1 inbox;
167 31 rherveille
 
168 33 rherveille
        always@(posedge clk)
169
                if (didat_wreq)
170
                        ddinbox <= #1 dinbox;
171
 
172
        always@(posedge clk)
173
                dddinbox <= #1 ddinbox;
174
 
175
        //
176
        // generate cursor buffer address counter
177
        always@(posedge clk)
178
                if (!cursor_en || ydone)
179
                        cbuf_ra <= #1 12'h0;
180
                else if (inbox && idat_wreq)
181
                        cbuf_ra <= #1 cbuf_ra +12'h1;
182
 
183
        always@(posedge clk)
184
                dcbuf_ra <= #1 cbuf_ra[2:0];
185
 
186
        assign cbuf_a = cursor_we ? cursor_wadr : cursor_res ? cbuf_ra[11:3] : cbuf_ra[9:1];
187
 
188 31 rherveille
        // hookup local cursor memory (generic synchronous single port memory)
189
        // cursor memory should never be written to/read from at the same time
190 33 rherveille
        generic_spram #(9, 32) cbuf(
191 31 rherveille
                .clk(clk),
192
                .rst(1'b0),       // no reset
193
                .ce(1'b1),        // always enable memory
194
                .we(cursor_we),
195
                .oe(1'b1),        // always output data
196 33 rherveille
                .addr(cbuf_a),
197
                .di(cursor_wdat),
198
                .do(cbuf_q)
199 31 rherveille
        );
200
 
201 33 rherveille
        //
202
        // decode cursor data for 32x32x16bpp mode
203
        always@(posedge clk)
204
                if (didat_wreq)
205 34 rherveille
                        cdat <= #1 dcbuf_ra[0] ? cbuf_q[31:16] : cbuf_q[15:0];
206 31 rherveille
 
207 33 rherveille
        always@(posedge clk)
208 34 rherveille
                dcdat <= #1 cdat;
209 31 rherveille
 
210 33 rherveille
        //
211
        // decode cursor data for 64x64x4bpp mode
212 31 rherveille
 
213 33 rherveille
        // generate cursor-color address
214
        always@(posedge clk)
215
                if (didat_wreq)
216
                        case (dcbuf_ra)
217
                                3'b000: cc_adr_o <= cbuf_q[ 3: 0];
218
                                3'b001: cc_adr_o <= cbuf_q[ 7: 4];
219
                                3'b010: cc_adr_o <= cbuf_q[11: 8];
220
                                3'b011: cc_adr_o <= cbuf_q[15:12];
221
                                3'b100: cc_adr_o <= cbuf_q[19:16];
222
                                3'b101: cc_adr_o <= cbuf_q[23:20];
223
                                3'b110: cc_adr_o <= cbuf_q[27:24];
224
                                3'b111: cc_adr_o <= cbuf_q[31:28];
225
                        endcase
226 31 rherveille
 
227 33 rherveille
        //
228
        // generate cursor colors
229 34 rherveille
        assign cursor_isalpha =  cursor_res ? cc_dat_i[15]    : dcdat[15];
230
        assign cursor_alpha   =  cursor_res ? cc_dat_i[7:0]   : dcdat[7:0];
231
        assign cursor_r       = {cursor_res ? cc_dat_i[14:10] : dcdat[14:10], 3'h0};
232
        assign cursor_g       = {cursor_res ? cc_dat_i[ 9: 5] : dcdat[ 9: 5], 3'h0};
233
        assign cursor_b       = {cursor_res ? cc_dat_i[ 4: 0] : dcdat[ 4: 0], 3'h0};
234 33 rherveille
 
235
        //
236 31 rherveille
        // delay image data
237
        always@(posedge clk)
238 33 rherveille
                didat <= #1 idat;
239 31 rherveille
 
240 33 rherveille
        always@(posedge clk)
241
                if (didat_wreq)
242
                        ddidat <= #1 didat;
243 31 rherveille
 
244 33 rherveille
        always@(posedge clk)
245
                dddidat <= #1 ddidat;
246
 
247
        always@(posedge clk)
248
                begin
249
                        didat_wreq  <= #1 idat_wreq;
250
                        ddidat_wreq <= #1 didat_wreq;
251
                end
252
 
253
        //
254 31 rherveille
        // generate selection unit
255
        always@(posedge clk)
256
                dcursor_en <= #1 cursor_en;
257
 
258
        always@(posedge clk)
259 33 rherveille
                if (didat_wreq)
260
                        ddcursor_en <= #1 dcursor_en;
261 31 rherveille
 
262 33 rherveille
        always@(posedge clk)
263
                dddcursor_en <= #1 ddcursor_en;
264 31 rherveille
 
265 34 rherveille
        // Alpha blending:
266
        // rgb = (rgb1 * alhpa1) + (rgb2 * alpha2)
267
        // We generate an alpha mixer (alpha1 + alpha2 = 1)
268
        // rgb = (alpha1)(rgb1) + (1-alpha1)(rgb2)
269
        // We always mix to black (rgb2 = 0)
270
        // rgb = (alpha1)(rgb1)
271 33 rherveille
        always@(posedge clk)
272
                if (ddidat_wreq)
273
                        if (!dddcursor_en || !dddinbox)
274
                                rgb <= #1 dddidat;
275 34 rherveille
                        else if (cursor_isalpha)
276
                                `ifdef VGA_HWC_3D
277
                                        rgb <= #1 dddidat * cursor_alpha;
278
                                `else
279
                                        rgb <= #1 dddidat;
280
                                `endif
281 33 rherveille
                        else
282
                                rgb <= #1 {cursor_r, cursor_g, cursor_b};
283
 
284
        //
285 31 rherveille
        // generate write request signal
286
        always@(posedge clk)
287
                if (rst_i)
288 33 rherveille
                begin
289
                        store1 <= #1 1'b0;
290
                        store2 <= #1 1'b0;
291
                end
292
                else
293
                begin
294
                        store1 <= #1  didat_wreq           | store1;
295
                        store2 <= #1 (didat_wreq & store1) | store2;
296
                end
297 31 rherveille
 
298 33 rherveille
        // skip 2 idat_wreq signal, to keep in pace with rgb_fifo_full signal
299 31 rherveille
        always@(posedge clk)
300 33 rherveille
                rgb_fifo_wreq <= #1 ddidat_wreq & store2;
301 31 rherveille
 
302
endmodule

powered by: WebSVN 2.1.0

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