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

Subversion Repositories vga_lcd

[/] [vga_lcd/] [trunk/] [rtl/] [verilog/] [vga_wb_master.v] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 23 rherveille
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3 30 rherveille
////  WISHBONE rev.B2 compliant enhanced VGA/LCD Core            ////
4 23 rherveille
////  Wishbone master interface                                  ////
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 30 rherveille
//// Copyright (C) 2001, 2002 Richard Herveille                  ////
15
////                          richard@asics.ws                   ////
16 23 rherveille
////                                                             ////
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 17 rherveille
//
40 57 rherveille
//  $Id: vga_wb_master.v,v 1.15 2003-08-01 11:46:38 rherveille Exp $
41 17 rherveille
//
42 57 rherveille
//  $Date: 2003-08-01 11:46:38 $
43
//  $Revision: 1.15 $
44 23 rherveille
//  $Author: rherveille $
45
//  $Locker:  $
46
//  $State: Exp $
47
//
48
// Change History:
49
//               $Log: not supported by cvs2svn $
50 57 rherveille
//               Revision 1.14  2003/05/07 09:48:54  rherveille
51
//               Fixed some Wishbone RevB.3 related bugs.
52
//               Changed layout of the core. Blocks are located more logically now.
53
//               Started work on a dual clocked/double edge 12bit output. Commonly used by external devices like DVI transmitters.
54
//
55 53 rherveille
//               Revision 1.13  2003/03/19 12:50:45  rherveille
56
//               Changed timing generator; made it smaller and easier.
57
//
58 45 rherveille
//               Revision 1.12  2003/03/18 21:45:48  rherveille
59
//               Added WISHBONE revB.3 Registered Feedback Cycles support
60
//
61 43 rherveille
//               Revision 1.11  2002/04/20 10:02:39  rherveille
62
//               Changed video timing generator.
63
//               Changed wishbone master vertical gate count code.
64
//               Fixed a potential bug in the wishbone slave (cursor color register readout).
65
//
66 39 rherveille
//               Revision 1.10  2002/03/28 04:59:25  rherveille
67
//               Fixed two small bugs that only showed up when the hardware cursors were disabled
68
//
69 36 rherveille
//               Revision 1.9  2002/03/04 16:05:52  rherveille
70
//               Added hardware cursor support to wishbone master.
71
//               Added provision to turn-off 3D cursors.
72
//               Fixed some minor bugs.
73
//
74 34 rherveille
//               Revision 1.8  2002/03/04 11:01:59  rherveille
75
//               Added 64x64pixels 4bpp hardware cursor support.
76
//
77 33 rherveille
//               Revision 1.7  2002/02/16 10:40:00  rherveille
78
//               Some minor bug-fixes.
79
//               Changed vga_ssel into vga_curproc (cursor processor).
80
//
81 31 rherveille
//               Revision 1.6  2002/02/07 05:42:10  rherveille
82
//               Fixed some bugs discovered by modified testbench
83
//               Removed / Changed some strange logic constructions
84
//               Started work on hardware cursor support (not finished yet)
85
//               Changed top-level name to vga_enh_top.v
86
//
87 17 rherveille
 
88 53 rherveille
//synopsys translate_off
89 17 rherveille
`include "timescale.v"
90 53 rherveille
//synopsys translate_on
91 17 rherveille
 
92 43 rherveille
module vga_wb_master (clk_i, rst_i, nrst_i,
93
        cyc_o, stb_o, cti_o, bte_o, we_o, adr_o, sel_o, ack_i, err_i, dat_i, sint,
94 53 rherveille
        ctrl_ven, ctrl_cd, ctrl_vbl, ctrl_vbsw, busy,
95 30 rherveille
        VBAa, VBAb, Thgate, Tvgate,
96 53 rherveille
        stat_avmp, vmem_switch, ImDoneFifoQ,
97
        cursor_adr, cursor0_ba, cursor1_ba, cursor0_ld, cursor1_ld,
98
        fb_data_fifo_rreq, fb_data_fifo_q, fb_data_fifo_empty);
99 17 rherveille
 
100
        // inputs & outputs
101
 
102
        // wishbone signals
103 19 rherveille
        input         clk_i;    // master clock input
104
        input         rst_i;    // synchronous active high reset
105
        input         nrst_i;   // asynchronous low reset
106
        output        cyc_o;    // cycle output
107
        reg cyc_o;
108
        output        stb_o;    // strobe ouput
109
        reg stb_o;
110 53 rherveille
        output [ 2:0] cti_o;    // cycle type id
111
        reg [2:0] cti_o;
112 43 rherveille
        output [ 1:0] bte_o;    // burst type extension
113
        reg [1:0] bte_o;
114 19 rherveille
        output        we_o;     // write enable output
115
        reg we_o;
116
        output [31:0] adr_o;    // address output
117
        output [ 3:0] sel_o;    // byte select outputs (only 32bits accesses are supported)
118
        reg [3:0] sel_o;
119 53 rherveille
        input         ack_i;    // wishbone cycle acknowledge
120 19 rherveille
        input         err_i;    // wishbone cycle error
121
        input [31:0]  dat_i;    // wishbone data in
122 17 rherveille
 
123 19 rherveille
        output        sint;     // non recoverable error, interrupt host
124 17 rherveille
 
125
        // control register settings
126
        input       ctrl_ven;   // video enable bit
127
        input [1:0] ctrl_cd;    // color depth
128
        input [1:0] ctrl_vbl;   // burst length
129
        input       ctrl_vbsw;  // enable video bank switching
130 53 rherveille
        output      busy;       // data transfer in progress
131 17 rherveille
 
132
        // video memory addresses
133
        input [31: 2] VBAa;     // video memory base address A
134
        input [31: 2] VBAb;     // video memory base address B
135
 
136
        input [15:0] Thgate;    // horizontal visible area (in pixels)
137
        input [15:0] Tvgate;    // vertical visible area (in horizontal lines)
138
 
139
        output stat_avmp;       // active video memory page
140 19 rherveille
        output vmem_switch;     // video memory bank-switch request: memory page switched (when enabled)
141 53 rherveille
        output ImDoneFifoQ;
142 17 rherveille
 
143 53 rherveille
        output [ 8: 0] cursor_adr; // cursor address
144
        input  [31:11] cursor0_ba;
145
        input  [31:11] cursor1_ba;
146
        input          cursor0_ld; // load cursor0 (from wbs)
147
        input          cursor1_ld; // load cursor1 (from wbs)
148 17 rherveille
 
149 53 rherveille
        input          fb_data_fifo_rreq;
150
        output [31: 0] fb_data_fifo_q;
151
        output         fb_data_fifo_empty;
152 19 rherveille
 
153 53 rherveille
 
154 17 rherveille
        //
155
        // variable declarations
156
        //
157 19 rherveille
 
158
        reg vmem_acc;                 // video memory access
159 53 rherveille
        wire vmem_req, vmem_ack;      // video memory access request // video memory access acknowledge
160 17 rherveille
 
161 53 rherveille
        wire ImDone;                  // Done reading image from video mem
162 19 rherveille
        reg  dImDone;                 // delayed ImDone
163 53 rherveille
        wire ImDoneStrb;              // image done (strobe signal)
164 19 rherveille
        reg  dImDoneStrb;             // delayed ImDoneStrb
165
 
166 53 rherveille
        reg sclr;                     // (video/cursor) synchronous clear
167 19 rherveille
 
168 34 rherveille
        // hardware cursors
169
        reg [31:11] cursor_ba;              // cursor pattern base address
170
        reg [ 8: 0] cursor_adr;             // cursor pattern offset
171
        wire        cursor0_we, cursor1_we; // cursor buffers write_request
172
        reg         ld_cursor0, ld_cursor1; // reload cursor0, cursor1
173
        reg         cur_acc;                // cursor processors request memory access
174
        reg         cur_acc_sel;            // which cursor to reload
175
        wire        cur_ack;                // cursor processor memory access acknowledge
176
        wire        cur_done;               // done reading cursor pattern
177 30 rherveille
 
178 17 rherveille
        //
179
        // module body
180
        //
181
 
182 19 rherveille
        // generate synchronous clear
183 43 rherveille
        always @(posedge clk_i)
184
          sclr <= #1 ~ctrl_ven;
185 53 rherveille
 
186 17 rherveille
        //
187
        // WISHBONE block
188
        //
189
        reg  [ 2:0] burst_cnt;                       // video memory burst access counter
190
        wire        burst_done;                      // completed burst access to video mem
191 19 rherveille
        reg         sel_VBA;                         // select video memory base address
192 43 rherveille
        reg  [31:2] vmemA;                           // video memory address
193 17 rherveille
 
194
        // wishbone access controller, video memory access request has highest priority (try to keep fifo full)
195 43 rherveille
        always @(posedge clk_i)
196
          if (sclr)
197
            vmem_acc <= #1 1'b0; // video memory access request
198
          else
199 53 rherveille
            vmem_acc <= #1 (vmem_req | (vmem_acc & !(burst_done & vmem_ack)) ) & !ImDone & !cur_acc;
200 17 rherveille
 
201 43 rherveille
        always @(posedge clk_i)
202
          if (sclr)
203
            cur_acc <= #1 1'b0; // cursor processor memory access request
204
          else
205
            cur_acc <= #1 (cur_acc | ImDone & (ld_cursor0 | ld_cursor1)) & !cur_done;
206 53 rherveille
 
207
        assign busy = vmem_acc | cur_acc;
208 34 rherveille
 
209 43 rherveille
        assign vmem_ack = ack_i & stb_o & vmem_acc;
210
        assign cur_ack  = ack_i & stb_o & cur_acc;
211 19 rherveille
        assign sint = err_i; // Non recoverable error, interrupt host system
212 17 rherveille
 
213 34 rherveille
 
214 19 rherveille
        // select active memory page
215
        assign vmem_switch = ImDoneStrb;
216 17 rherveille
 
217 43 rherveille
        always @(posedge clk_i)
218
          if (sclr)
219
            sel_VBA <= #1 1'b0;
220
          else if (ctrl_vbsw)
221
            sel_VBA <= #1 sel_VBA ^ vmem_switch;  // select next video memory bank when finished reading current bank (and bank switch enabled)
222 17 rherveille
 
223
        assign stat_avmp = sel_VBA; // assign output
224
 
225 30 rherveille
        // selecting active clut page / cursor data
226
        // delay image done same amount as video-memory data
227 19 rherveille
        vga_fifo #(4, 1) clut_sw_fifo (
228 53 rherveille
                .clk    ( clk_i             ),
229
                .aclr   ( 1'b1              ),
230
                .sclr   ( sclr              ),
231
                .d      ( ImDone            ),
232
                .wreq   ( vmem_ack          ),
233
                .q      ( ImDoneFifoQ       ),
234
                .rreq   ( fb_data_fifo_rreq ),
235
                .nword  ( ),
236
                .empty  ( ),
237
                .full   ( ),
238
                .aempty ( ),
239
                .afull  ( )
240 19 rherveille
        );
241
 
242
 
243 34 rherveille
        //
244 17 rherveille
        // generate burst counter
245
        wire [3:0] burst_cnt_val;
246
        assign burst_cnt_val = {1'b0, burst_cnt} -4'h1;
247
        assign burst_done = burst_cnt_val[3];
248
 
249 43 rherveille
        always @(posedge clk_i)
250
          if ( (burst_done & vmem_ack) | !vmem_acc)
251
            case (ctrl_vbl) // synopsis full_case parallel_case
252
              2'b00: burst_cnt <= #1 3'b000; // burst length 1
253
              2'b01: burst_cnt <= #1 3'b001; // burst length 2
254
              2'b10: burst_cnt <= #1 3'b011; // burst length 4
255
              2'b11: burst_cnt <= #1 3'b111; // burst length 8
256
            endcase
257
          else if(vmem_ack)
258
            burst_cnt <= #1 burst_cnt_val[2:0];
259 17 rherveille
 
260
        //
261
        // generate image counters
262
        //
263
 
264
        // hgate counter
265 19 rherveille
        reg  [15:0] hgate_cnt;
266
        reg  [16:0] hgate_cnt_val;
267
        reg  [1:0]  hgate_div_cnt;
268
        reg  [2:0]  hgate_div_val;
269 17 rherveille
 
270 19 rherveille
        wire hdone = hgate_cnt_val[16] & vmem_ack; // ????
271
 
272 43 rherveille
        always @(hgate_cnt or hgate_div_cnt or ctrl_cd)
273
          begin
274
              hgate_div_val = {1'b0, hgate_div_cnt} - 3'h1;
275 17 rherveille
 
276 43 rherveille
              if (ctrl_cd != 2'b10)
277
                hgate_cnt_val = {1'b0, hgate_cnt} - 17'h1;
278
              else if ( hgate_div_val[2] )
279
                hgate_cnt_val = {1'b0, hgate_cnt} - 17'h1;
280
              else
281
                hgate_cnt_val = {1'b0, hgate_cnt};
282
          end
283 19 rherveille
 
284 43 rherveille
        always @(posedge clk_i)
285
          if (sclr)
286
            begin
287
                case(ctrl_cd) // synopsys full_case parallel_case
288
                  2'b00: hgate_cnt <= #1 Thgate >> 2; //  8bpp, 4 pixels per cycle
289
                  2'b01: hgate_cnt <= #1 Thgate >> 1; // 16bpp, 2 pixels per cycle
290
                  2'b10: hgate_cnt <= #1 Thgate >> 2; // 24bpp, 4/3 pixels per cycle
291
                  2'b11: hgate_cnt <= #1 Thgate;      // 32bpp, 1 pixel per cycle
292
                endcase
293 19 rherveille
 
294 43 rherveille
                hgate_div_cnt <= 2'b10;
295
            end
296
          else if (vmem_ack)
297
            if (hdone)
298
              begin
299
                  case(ctrl_cd) // synopsys full_case parallel_case
300
                    2'b00: hgate_cnt <= #1 Thgate >> 2; //  8bpp, 4 pixels per cycle
301
                    2'b01: hgate_cnt <= #1 Thgate >> 1; // 16bpp, 2 pixels per cycle
302
                    2'b10: hgate_cnt <= #1 Thgate >> 2; // 24bpp, 4/3 pixels per cycle
303
                    2'b11: hgate_cnt <= #1 Thgate;      // 32bpp, 1 pixel per cycle
304
                  endcase
305 19 rherveille
 
306 43 rherveille
                  hgate_div_cnt <= 2'b10;
307
              end
308
            else //if (vmem_ack)
309
              begin
310
                  hgate_cnt <= #1 hgate_cnt_val[15:0];
311
 
312
                  if ( hgate_div_val[2] )
313
                    hgate_div_cnt <= #1 2'b10;
314
                  else
315
                    hgate_div_cnt <= #1 hgate_div_val[1:0];
316
              end
317
 
318 17 rherveille
        // vgate counter
319 19 rherveille
        reg  [15:0] vgate_cnt;
320 45 rherveille
        wire [16:0] vgate_cnt_val;
321
        wire        vdone;
322 17 rherveille
 
323 45 rherveille
        assign vgate_cnt_val = {1'b0, vgate_cnt} - 17'h1;
324
        assign vdone = vgate_cnt_val[16];
325
 
326 43 rherveille
        always @(posedge clk_i)
327 53 rherveille
          if (sclr | ImDoneStrb)
328 43 rherveille
            vgate_cnt <= #1 Tvgate;
329
          else if (hdone)
330 45 rherveille
            vgate_cnt <= #1 vgate_cnt_val[15:0];
331 17 rherveille
 
332 30 rherveille
        assign ImDone = hdone & vdone;
333 19 rherveille
 
334 17 rherveille
        assign ImDoneStrb = ImDone & !dImDone;
335
 
336 43 rherveille
        always @(posedge clk_i)
337
          begin
338
              dImDone <= #1 ImDone;
339
              dImDoneStrb <= #1 ImDoneStrb;
340
          end
341 17 rherveille
 
342
        //
343
        // generate addresses
344
        //
345
 
346
        // select video memory base address
347 43 rherveille
        always @(posedge clk_i)
348 53 rherveille
          if (sclr | dImDoneStrb)
349 43 rherveille
            if (!sel_VBA)
350
              vmemA <= #1 VBAa;
351
            else
352
              vmemA <= #1 VBAb;
353
          else if (vmem_ack)
354
            vmemA <= #1 vmemA +30'h1;
355 17 rherveille
 
356 34 rherveille
 
357
        ////////////////////////////////////
358
        // hardware cursor signals section
359
        //
360 43 rherveille
        always @(posedge clk_i)
361
          if (ImDone)
362
            cur_acc_sel <= #1 ld_cursor0; // cursor0 has highest priority
363 34 rherveille
 
364 43 rherveille
        always @(posedge clk_i)
365 34 rherveille
        if (sclr)
366 43 rherveille
          begin
367
              ld_cursor0 <= #1 1'b0;
368
              ld_cursor1 <= #1 1'b0;
369
          end
370 34 rherveille
        else
371 43 rherveille
          begin
372
              ld_cursor0 <= #1 cursor0_ld | (ld_cursor0 & !(cur_done &  cur_acc_sel));
373
              ld_cursor1 <= #1 cursor1_ld | (ld_cursor1 & !(cur_done & !cur_acc_sel));
374
          end
375 34 rherveille
 
376
        // select cursor base address
377 43 rherveille
        always @(posedge clk_i)
378
          if (!cur_acc)
379
            cursor_ba <= #1 ld_cursor0 ? cursor0_ba : cursor1_ba;
380 34 rherveille
 
381
        // generate pattern offset
382
        wire [9:0] next_cursor_adr = {1'b0, cursor_adr} + 10'h1;
383 43 rherveille
        assign cur_done = next_cursor_adr[9] & cur_ack;
384 34 rherveille
 
385 43 rherveille
        always @(posedge clk_i)
386
          if (!cur_acc)
387
            cursor_adr <= #1 9'h0;
388
          else if (cur_ack)
389
            cursor_adr <= #1 next_cursor_adr;
390 34 rherveille
 
391
        // generate cursor buffers write enable signals
392
        assign cursor1_we = cur_ack & !cur_acc_sel;
393
        assign cursor0_we = cur_ack &  cur_acc_sel;
394
 
395
 
396
        //////////////////////////////
397 17 rherveille
        // generate wishbone signals
398 34 rherveille
        //
399
        assign adr_o = cur_acc ? {cursor_ba, cursor_adr, 2'b00} : {vmemA, 2'b00};
400 53 rherveille
        wire wb_cycle = vmem_acc & !(burst_done & vmem_ack & !vmem_req) & !ImDone ||
401 34 rherveille
                        cur_acc & !cur_done;
402 17 rherveille
 
403 43 rherveille
        always @(posedge clk_i or negedge nrst_i)
404
          if (!nrst_i)
405
            begin
406
                cyc_o <= #1 1'b0;
407
                stb_o <= #1 1'b0;
408
                sel_o <= #1 4'b1111;
409
                cti_o <= #1 3'b000;
410
                bte_o <= #1 2'b00;
411
                we_o  <= #1 1'b0;
412
            end
413
          else
414
            if (rst_i)
415
              begin
416
                  cyc_o <= #1 1'b0;
417
                  stb_o <= #1 1'b0;
418
                  sel_o <= #1 4'b1111;
419
                  cti_o <= #1 3'b000;
420
                  bte_o <= #1 2'b00;
421
                  we_o  <= #1 1'b0;
422
              end
423
            else
424
              begin
425
                  cyc_o <= #1 wb_cycle;
426
                  stb_o <= #1 wb_cycle;
427
                  sel_o <= #1 4'b1111;   // only 32bit accesses are supported
428
 
429 53 rherveille
                  if (wb_cycle) begin
430
                    if (cur_acc)
431
                      cti_o <= #1 &next_cursor_adr[8:0] ? 3'b111 : 3'b010;
432
                    else if (ctrl_vbl == 2'b00)
433
                      cti_o <= #1 3'b000;
434
                    else if (vmem_ack)
435
                      cti_o <= #1 (burst_cnt == 3'h1) ? 3'b111 : 3'b010;
436
                  end else
437
                    cti_o <= #1 (ctrl_vbl == 2'b00) ? 3'b000 : 3'b010;
438 43 rherveille
 
439
                  bte_o <= #1 2'b00;     // linear burst
440 53 rherveille
                  we_o  <= #1 1'b0;      // read only
441 43 rherveille
              end
442
 
443 34 rherveille
        //
444 30 rherveille
        // video-data buffer (temporary store data read from video memory)
445 57 rherveille
        wire [4:0] fb_data_fifo_nword;
446
//      wire       fb_data_fifo_full;
447 53 rherveille
 
448 19 rherveille
        vga_fifo #(4, 32) data_fifo (
449 53 rherveille
                .clk    ( clk_i              ),
450
                .aclr   ( 1'b1               ),
451
                .sclr   ( sclr               ),
452
                .d      ( dat_i              ),
453
                .wreq   ( vmem_ack           ),
454
                .q      ( fb_data_fifo_q     ),
455
                .rreq   ( fb_data_fifo_rreq  ),
456
                .nword  ( fb_data_fifo_nword ),
457
                .empty  ( fb_data_fifo_empty ),
458 57 rherveille
                .full   ( ),//fb_data_fifo_full  ),
459 53 rherveille
                .aempty ( ),
460
                .afull  ( )
461 17 rherveille
        );
462
 
463 57 rherveille
        assign vmem_req = ~fb_data_fifo_nword[4] & ~fb_data_fifo_nword[3];
464 17 rherveille
 
465
endmodule

powered by: WebSVN 2.1.0

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