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 53

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

powered by: WebSVN 2.1.0

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