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

Subversion Repositories rtfbitmapcontroller

[/] [rtfbitmapcontroller/] [trunk/] [rtl/] [verilog/] [rtfBitmapController5.v] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 23 robfinch
// ============================================================================
2
// rtfBitmapController5
3
//  Bitmap Controller (Frame Buffer Display)
4
//  - Displays a bitmap from memory.
5
//
6
//
7
//        __
8 24 robfinch
//   \\__/ o\    (C) 2008-2019  Robert Finch, Waterloo
9 23 robfinch
//    \  __ /    All rights reserved.
10
//     \/_//     robfinch<remove>@finitron.ca
11
//       ||
12
//
13
//
14
// This source file is free software: you can redistribute it and/or modify 
15
// it under the terms of the GNU Lesser General Public License as published 
16
// by the Free Software Foundation, either version 3 of the License, or     
17
// (at your option) any later version.                                      
18
//                                                                          
19
// This source file is distributed in the hope that it will be useful,      
20
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
21
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
22
// GNU General Public License for more details.                             
23
//                                                                          
24
// You should have received a copy of the GNU General Public License        
25
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
26
//                                                                          
27
//
28
//  The default base screen address is:
29 24 robfinch
//              $0200000 - the third meg of RAM
30 23 robfinch
//
31
//
32
//      Verilog 1995
33
//
34
// ============================================================================
35
 
36
//`define USE_CLOCK_GATE        1'b1
37
`define INTERNAL_SYNC_GEN       1'b1
38
 
39
`define ABITS   31:0
40
`define HIGH    1'b1
41
`define LOW             1'b0
42 24 robfinch
`define TRUE    1'b1
43
`define FALSE   1'b0
44 23 robfinch
 
45
module rtfBitmapController5(
46 24 robfinch
        rst_i, irq_o,
47
        s_clk_i, s_cs_i, s_cyc_i, s_stb_i, s_ack_o, s_we_i, s_sel_i, s_adr_i, s_dat_i, s_dat_o,
48 23 robfinch
        m_clk_i, m_cyc_o, m_stb_o, m_ack_i, m_we_o, m_sel_o, m_adr_o, m_dat_i, m_dat_o,
49
        dot_clk_i, zrgb_o, xonoff_i
50
`ifdef INTERNAL_SYNC_GEN
51 24 robfinch
        , hsync_o, vsync_o, blank_o, border_o, hctr_o, vctr_o, fctr_o
52 23 robfinch
`else
53
        , hsync_i, vsync_i, blank_i
54
`endif
55
);
56 24 robfinch
parameter MDW = 128;            // Bus master data width
57 23 robfinch
parameter BM_BASE_ADDR1 = 32'h0020_0000;
58
parameter BM_BASE_ADDR2 = 32'h0028_0000;
59
parameter REG_CTRL = 9'd0;
60
parameter REG_DISPLAYED = 9'd1;
61
parameter REG_PAGE1ADDR = 9'd2;
62
parameter REG_PAGE2ADDR = 9'd3;
63
parameter REG_PXYZ = 9'd4;
64
parameter REG_PCOLCMD = 9'd5;
65
parameter REG_TOTAL = 9'd8;
66
parameter REG_SYNC_ONOFF = 9'd9;
67
parameter REG_BLANK_ONOFF = 9'd10;
68
parameter REG_BORDER_ONOFF = 9'd11;
69 24 robfinch
parameter REG_RASTCMP = 9'd12;
70 23 robfinch
 
71
parameter BPP4 = 3'd0;
72
parameter BPP8 = 3'd1;
73
parameter BPP12 = 3'd2;
74
parameter BPP16 = 3'd3;
75
parameter BPP20 = 3'd4;
76
parameter BPP32 = 3'd5;
77
 
78
parameter OPBLACK = 4'd0;
79
parameter OPCOPY = 4'd1;
80
parameter OPINV = 4'd2;
81
parameter OPAND = 4'd4;
82
parameter OPOR = 4'd5;
83
parameter OPXOR = 4'd6;
84
parameter OPANDN = 4'd7;
85
parameter OPNAND = 4'd8;
86
parameter OPNOR = 4'd9;
87
parameter OPXNOR = 4'd10;
88
parameter OPORN = 4'd11;
89
parameter OPWHITE = 4'd15;
90
 
91
// Sync Generator defaults: 800x600 60Hz
92
parameter phSyncOn  = 40;               //   40 front porch
93
parameter phSyncOff = 168;              //  128 sync
94
parameter phBlankOff = 252;     //256   //   88 back porch
95
//parameter phBorderOff = 336;  //   80 border
96
parameter phBorderOff = 256;    //   80 border
97
//parameter phBorderOn = 976;           //  640 display
98
parameter phBorderOn = 1056;            //  640 display
99
parameter phBlankOn = 1052;             //   80 border
100
parameter phTotal = 1056;               // 1056 total clocks
101
parameter pvSyncOn  = 1;                //    1 front porch
102
parameter pvSyncOff = 5;                //    4 vertical sync
103
parameter pvBlankOff = 28;              //   23 back porch
104
parameter pvBorderOff = 28;             //   44 border  0
105
//parameter pvBorderOff = 72;           //   44 border  0
106
parameter pvBorderOn = 628;             //  512 display
107
//parameter pvBorderOn = 584;           //  512 display
108
parameter pvBlankOn = 628;      //   44 border  0
109
parameter pvTotal = 628;                //  628 total scan lines
110
 
111
 
112
// SYSCON
113
input rst_i;                            // system reset
114 24 robfinch
output irq_o;
115 23 robfinch
 
116
// Peripheral IO slave port
117
input s_clk_i;
118
input s_cs_i;
119
input s_cyc_i;
120
input s_stb_i;
121
output s_ack_o;
122
input s_we_i;
123
input [7:0] s_sel_i;
124
input [11:0] s_adr_i;
125
input [63:0] s_dat_i;
126
output [63:0] s_dat_o;
127
reg [63:0] s_dat_o;
128
 
129
// Video Memory Master Port
130
// Used to read memory via burst access
131
input m_clk_i;                          // system bus interface clock
132
output m_cyc_o;                 // video burst request
133
output m_stb_o;
134
output reg m_we_o;
135 24 robfinch
output [MDW/8-1:0] m_sel_o;
136 23 robfinch
input  m_ack_i;                 // vid_acknowledge from memory
137
output [`ABITS] m_adr_o;        // address for memory access
138 24 robfinch
input  [MDW-1:0] m_dat_i;        // memory data input
139
output reg [MDW-1:0] m_dat_o;
140 23 robfinch
 
141
// Video
142
input dot_clk_i;                // Video clock 80 MHz
143
`ifdef INTERNAL_SYNC_GEN
144
output hsync_o;
145
output vsync_o;
146
output blank_o;
147
output border_o;
148 24 robfinch
output [11:0] hctr_o;
149
output [11:0] vctr_o;
150
output [5:0] fctr_o;
151 23 robfinch
`else
152
input hsync_i;                  // start/end of scan line
153
input vsync_i;                  // start/end of frame
154
input blank_i;                  // blank the output
155
`endif
156
output [31:0] zrgb_o;            // 24-bit RGB output + z-order
157
reg [31:0] zrgb_o;
158
 
159
input xonoff_i;
160
 
161
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
162
// IO registers
163
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
164 24 robfinch
reg irq_o;
165 23 robfinch
reg m_cyc_o;
166
reg [31:0] m_adr_o;
167
 
168
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
169
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
170 24 robfinch
wire vclk;
171
reg cs;
172
reg we;
173
reg [7:0] sel;
174
reg [11:0] adri;
175
reg [63:0] dat;
176
 
177 23 robfinch
always @(posedge s_clk_i)
178 24 robfinch
        cs <= s_cyc_i & s_stb_i & s_cs_i;
179
always @(posedge s_clk_i)
180
        we <= s_we_i;
181
always @(posedge s_clk_i)
182
        sel <= s_sel_i;
183
always @(posedge s_clk_i)
184
        adri <= s_adr_i;
185
always @(posedge s_clk_i)
186
        dat <= s_dat_i;
187 23 robfinch
 
188 24 robfinch
ack_gen #(
189
        .READ_STAGES(2),
190
        .WRITE_STAGES(0),
191
        .REGISTER_OUTPUT(1)
192
) uag1
193
(
194
        .clk_i(s_clk_i),
195
        .ce_i(1'b1),
196
        .i(cs),
197
        .we_i(s_cyc_i & s_stb_i & s_cs_i & s_we_i),
198
        .o(s_ack_o)
199
);
200
 
201 23 robfinch
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
203
integer n;
204
reg [11:0] hDisplayed,vDisplayed;
205 24 robfinch
reg [11:0] rastcmp;
206 23 robfinch
reg [`ABITS] bm_base_addr1,bm_base_addr2;
207
reg [2:0] color_depth;
208
wire [7:0] fifo_cnt;
209
reg onoff;
210
reg [2:0] hres,vres;
211
reg greyscale;
212
reg page;
213
reg pals;                               // palette select
214
reg [11:0] hrefdelay;
215
reg [11:0] vrefdelay;
216
reg [11:0] map;     // memory access period
217
reg [11:0] mapctr;
218
reg [`ABITS] baseAddr;  // base address register
219 24 robfinch
wire [63:0] rgbo1;
220 23 robfinch
reg [11:0] pixelRow;
221
reg [11:0] pixelCol;
222
wire [31:0] pal_wo;
223
wire [31:0] pal_o;
224
reg [11:0] px;
225
reg [11:0] py;
226
reg [7:0] pz;
227
reg [1:0] pcmd,pcmd_o;
228
reg [3:0] raster_op;
229
reg [31:0] color;
230
reg [31:0] color_o;
231
reg rstcmd,rstcmd1;
232
reg [11:0] hTotal = phTotal;
233
reg [11:0] vTotal = pvTotal;
234
reg [11:0] hSyncOn = phSyncOn, hSyncOff = phSyncOff;
235
reg [11:0] vSyncOn = pvSyncOn, vSyncOff = pvSyncOff;
236
reg [11:0] hBlankOn = phBlankOn, hBlankOff = phBlankOff;
237
reg [11:0] vBlankOn = pvBlankOn, vBlankOff = pvBlankOff;
238
reg [11:0] hBorderOn = phBorderOn, hBorderOff = phBorderOff;
239
reg [11:0] vBorderOn = pvBorderOn, vBorderOff = pvBorderOff;
240
reg sgLock;
241 24 robfinch
wire pe_hsync, pe_hsync2;
242
wire pe_vsync;
243 23 robfinch
 
244
`ifdef INTERNAL_SYNC_GEN
245
wire hsync_i, vsync_i, blank_i;
246
 
247
VGASyncGen usg1
248
(
249
        .rst(rst_i),
250
        .clk(vclk),
251
        .eol(),
252
        .eof(),
253
        .hSync(hsync_o),
254
        .vSync(vsync_o),
255 24 robfinch
        .hCtr(hctr_o),
256
        .vCtr(vctr_o),
257 23 robfinch
  .blank(blank_o),
258
  .vblank(vblank),
259
  .vbl_int(),
260
  .border(border_o),
261
  .hTotal_i(hTotal),
262
  .vTotal_i(vTotal),
263
  .hSyncOn_i(hSyncOn),
264
  .hSyncOff_i(hSyncOff),
265
  .vSyncOn_i(vSyncOn),
266
  .vSyncOff_i(vSyncOff),
267
  .hBlankOn_i(hBlankOn),
268
  .hBlankOff_i(hBlankOff),
269
  .vBlankOn_i(vBlankOn),
270
  .vBlankOff_i(vBlankOff),
271
  .hBorderOn_i(hBorderOn),
272
  .hBorderOff_i(hBorderOff),
273
  .vBorderOn_i(vBorderOn),
274
  .vBorderOff_i(vBorderOff)
275
);
276
assign hsync_i = hsync_o;
277
assign vsync_i = vsync_o;
278
assign blank_i = blank_o;
279
`endif
280
 
281
edge_det edcs1
282
(
283
        .rst(rst_i),
284
        .clk(s_clk_i),
285
        .ce(1'b1),
286
        .i(cs),
287
        .pe(cs_edge),
288
        .ne(),
289
        .ee()
290
);
291
 
292 24 robfinch
// Frame counter
293
//
294
VT163 #(6) ub1
295
(
296
        .clk(vclk),
297
        .clr_n(!rst_i),
298
        .ent(pe_vsync),
299
        .enp(1'b1),
300
        .ld_n(1'b1),
301
        .d(6'd0),
302
        .q(fctr_o),
303
        .rco()
304
);
305 23 robfinch
 
306 24 robfinch
reg rst_irq;
307
always @(posedge vclk)
308
if (rst_i)
309
        irq_o <= `LOW;
310
else begin
311
        if (hctr_o==12'd02 && rastcmp==vctr_o)
312
                irq_o <= `HIGH;
313
        else if (rst_irq)
314
                irq_o <= `LOW;
315
end
316
 
317 23 robfinch
always @(page or bm_base_addr1 or bm_base_addr2)
318
        baseAddr = page ? bm_base_addr2 : bm_base_addr1;
319
 
320
// Color palette RAM for 8bpp modes
321
syncRam512x32_1rw1r upal1
322
(
323
        .wrst(1'b0),
324
        .wclk(s_clk_i),
325 24 robfinch
        .wce(cs & adri[11]),
326
        .we(we),
327
        .wadr({2'b0,adri[9:3]}),
328
        .i(dat[31:0]),
329 23 robfinch
        .wo(pal_wo),
330
        .rrst(1'b0),
331
        .rclk(vclk),
332
        .rce(1'b1),
333
        .radr({2'b0,pals,rgbo4[5:0]}),
334
        .o(pal_o)
335
);
336
 
337
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
338
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
339
always @(posedge s_clk_i)
340
if (rst_i) begin
341
        page <= 1'b0;
342
        pals <= 1'b0;
343
        hres <= 3'd2;
344
        vres <= 3'd2;
345
        hDisplayed <= 12'd400;
346
        vDisplayed <= 12'd300;
347
        onoff <= 1'b1;
348
        color_depth <= BPP16;
349
        greyscale <= 1'b0;
350
        bm_base_addr1 <= BM_BASE_ADDR1;
351
        bm_base_addr2 <= BM_BASE_ADDR2;
352 24 robfinch
        hrefdelay <= 12'd103;//12'd218;
353
        vrefdelay <= 12'd13;//12'd27;
354 23 robfinch
        map <= 12'd0;
355
        pcmd <= 2'b00;
356
        rstcmd1 <= 1'b0;
357 24 robfinch
        rst_irq <= 1'b0;
358
        rastcmp <= 12'hFFF;
359 23 robfinch
end
360
else begin
361
        rstcmd1 <= rstcmd;
362 24 robfinch
        rst_irq <= 1'b0;
363 23 robfinch
  if (rstcmd & ~rstcmd1)
364
    pcmd <= 2'b00;
365
        if (cs_edge) begin
366 24 robfinch
                if (we) begin
367
                        casez(adri[11:3])
368 23 robfinch
                        REG_CTRL:
369
                                begin
370 24 robfinch
                                        if (sel[0]) onoff <= dat[0];
371
                                        if (sel[1]) begin
372
                                        color_depth <= dat[10:8];
373
                                        greyscale <= dat[11];
374 23 robfinch
                                        end
375 24 robfinch
                                        if (sel[2]) begin
376
                                        hres <= dat[18:16];
377
                                        vres <= dat[21:19];
378 23 robfinch
                                        end
379 24 robfinch
                                        if (sel[3]) begin
380
                                        page <= dat[24];
381
                                        pals <= dat[25];
382 23 robfinch
                                        end
383 24 robfinch
                                        if (|sel[7:6]) map <= dat[59:48];
384 23 robfinch
                                end
385
                        REG_DISPLAYED:
386
                                begin
387 24 robfinch
                                        if (|sel[1:0])   hDisplayed <= dat[11:0];
388
                                        if (|sel[3:2])  vDisplayed <= dat[27:16];
389
                                        if (|sel[5:4])  hrefdelay <= dat[43:32];
390
                                        if (|sel[7:6])  vrefdelay <= dat[59:48];
391 23 robfinch
                                end
392 24 robfinch
                        REG_PAGE1ADDR:  bm_base_addr1 <= dat;
393
                        REG_PAGE2ADDR:  bm_base_addr2 <= dat;
394 23 robfinch
                        REG_PXYZ:
395
                                begin
396 24 robfinch
                                        if (|sel[1:0])   px <= dat[11:0];
397
                                        if (|sel[3:2])  py <= dat[27:16];
398
                                        if (|sel[  4])  pz <= dat[39:32];
399 23 robfinch
                                end
400
                        REG_PCOLCMD:
401
                                begin
402 24 robfinch
                                        if (sel[0]) pcmd <= dat[1:0];
403
                            if (sel[2]) raster_op <= dat[19:16];
404
                            if (|sel[7:4]) color <= dat[63:32];
405 23 robfinch
                          end
406 24 robfinch
                        REG_RASTCMP:
407
                                begin
408
                                        if (sel[0]) rastcmp[7:0] <= dat[7:0];
409
                                        if (sel[1]) rastcmp[11:8] <= dat[11:8];
410
                                        if (sel[7]) rst_irq <= dat[63];
411
                                end
412 23 robfinch
`ifdef INTERNAL_SYNC_GEN
413
                        REG_TOTAL:
414
                                begin
415
                                        if (!sgLock) begin
416 24 robfinch
                                                if (|sel[1:0]) hTotal <= dat[11:0];
417
                                                if (|sel[3:2]) vTotal <= dat[27:16];
418 23 robfinch
                                        end
419 24 robfinch
                                        if (|sel[7:4]) begin
420
                                                if (dat[63:32]==32'hA1234567)
421 23 robfinch
                                                        sgLock <= 1'b0;
422 24 robfinch
                                                else if (dat[63:32]==32'h7654321A)
423 23 robfinch
                                                        sgLock <= 1'b1;
424
                                        end
425
                                end
426
                        REG_SYNC_ONOFF:
427
                                if (!sgLock) begin
428 24 robfinch
                                        if (|sel[1:0]) hSyncOff <= dat[11:0];
429
                                        if (|sel[3:2]) hSyncOn <= dat[27:16];
430
                                        if (|sel[5:4]) vSyncOff <= dat[43:32];
431
                                        if (|sel[7:6]) vSyncOn <= dat[59:48];
432 23 robfinch
                                end
433
                        REG_BLANK_ONOFF:
434
                                if (!sgLock) begin
435 24 robfinch
                                        if (|sel[1:0]) hBlankOff <= dat[11:0];
436
                                        if (|sel[3:2]) hBlankOn <= dat[27:16];
437
                                        if (|sel[5:4]) vBlankOff <= dat[43:32];
438
                                        if (|sel[7:6]) vBlankOn <= dat[59:48];
439 23 robfinch
                                end
440
                        REG_BORDER_ONOFF:
441
                                begin
442 24 robfinch
                                        if (|sel[1:0]) hBorderOff <= dat[11:0];
443
                                        if (|sel[3:2]) hBorderOn <= dat[27:16];
444
                                        if (|sel[5:4]) vBorderOff <= dat[43:32];
445
                                        if (|sel[7:6]) vBorderOn <= dat[59:48];
446 23 robfinch
                                end
447
`endif
448
      default:  ;
449
                        endcase
450
                end
451
        end
452 24 robfinch
  casez(adri[11:3])
453 23 robfinch
  REG_CTRL:
454
      begin
455
          s_dat_o[0] <= onoff;
456
          s_dat_o[10:8] <= color_depth;
457
          s_dat_o[11] <= greyscale;
458
          s_dat_o[18:16] <= hres;
459
          s_dat_o[21:19] <= vres;
460
          s_dat_o[24] <= page;
461
          s_dat_o[25] <= pals;
462
          s_dat_o[59:48] <= map;
463
      end
464
  REG_DISPLAYED:        s_dat_o <= {4'h0,vrefdelay,4'h0,hrefdelay,4'h0,vDisplayed,4'h0,hDisplayed};
465
  REG_PAGE1ADDR:        s_dat_o <= bm_base_addr1;
466
  REG_PAGE2ADDR:        s_dat_o <= bm_base_addr2;
467
  REG_PXYZ:                 s_dat_o <= {20'h0,pz,4'h0,py,4'h0,px};
468
  REG_PCOLCMD:    s_dat_o <= {color_o,12'd0,raster_op,14'd0,pcmd};
469
  9'b10??_????_?:       s_dat_o <= {32'h0,pal_wo};
470
  default:        s_dat_o <= 64'd0;
471
  endcase
472
end
473
 
474
`ifdef USE_CLOCK_GATE
475
BUFHCE ucb1
476
(
477
        .I(dot_clk_i),
478
        .CE(onoff),
479
        .O(vclk)
480
);
481
`else
482
assign vclk = dot_clk_i;
483
`endif
484
 
485
 
486
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
487
// Horizontal and Vertical timing reference counters
488
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
489
 
490
edge_det edh1
491
(
492
        .rst(rst_i),
493
        .clk(vclk),
494
        .ce(1'b1),
495
        .i(hsync_i),
496
        .pe(pe_hsync),
497
        .ne(),
498
        .ee()
499
);
500
 
501
edge_det edh2
502
(
503
        .rst(rst_i),
504
        .clk(m_clk_i),
505
        .ce(1'b1),
506
        .i(hsync_i),
507
        .pe(pe_hsync2),
508
        .ne(),
509
        .ee()
510
);
511
 
512
edge_det edv1
513
(
514
        .rst(rst_i),
515
        .clk(vclk),
516
        .ce(1'b1),
517
        .i(vsync_i),
518
        .pe(pe_vsync),
519
        .ne(),
520
        .ee()
521
);
522
 
523
reg [3:0] hc;
524
always @(posedge vclk)
525
if (rst_i)
526
        hc <= 4'd1;
527
else if (pe_hsync) begin
528
        hc <= 4'd1;
529
        pixelCol <= -hrefdelay;
530
end
531
else begin
532
        if (hc==hres) begin
533
                hc <= 4'd1;
534
                pixelCol <= pixelCol + 1;
535
        end
536
        else
537
                hc <= hc + 4'd1;
538
end
539
 
540
reg [3:0] vc;
541
always @(posedge vclk)
542
if (rst_i)
543
        vc <= 4'd1;
544
else if (pe_vsync) begin
545
        vc <= 4'd1;
546
        pixelRow <= -vrefdelay;
547
end
548
else begin
549
        if (pe_hsync) begin
550
                vc <= vc + 4'd1;
551
                if (vc==vres) begin
552
                        vc <= 4'd1;
553
                        pixelRow <= pixelRow + 1;
554
                end
555
        end
556
end
557
 
558
// Bits per pixel minus one.
559
reg [4:0] bpp;
560
always @(color_depth)
561
case(color_depth)
562
BPP4: bpp = 3;
563
BPP8:   bpp = 7;
564
BPP12: bpp = 11;
565
BPP16:  bpp = 15;
566
BPP20:  bpp = 19;
567
BPP32:  bpp = 31;
568 24 robfinch
default:        bpp = 15;
569 23 robfinch
endcase
570
 
571
reg [5:0] shifts;
572
always @(color_depth)
573 24 robfinch
case(MDW)
574
128:
575
        case(color_depth)
576
        BPP4:   shifts = 6'd32;
577
        BPP8:   shifts = 6'd16;
578
        BPP12:  shifts = 6'd10;
579
        BPP16:  shifts = 6'd8;
580
        BPP20:  shifts = 6'd6;
581
        BPP32:  shifts = 6'd4;
582
        default:  shifts = 6'd8;
583
        endcase
584
64:
585
        case(color_depth)
586
        BPP4:   shifts = 6'd16;
587
        BPP8:   shifts = 6'd8;
588
        BPP12:  shifts = 6'd5;
589
        BPP16:  shifts = 6'd4;
590
        BPP20:  shifts = 6'd3;
591
        BPP32:  shifts = 6'd2;
592
        default:  shifts = 6'd4;
593
        endcase
594
32:
595
        case(color_depth)
596
        BPP4:   shifts = 6'd8;
597
        BPP8:   shifts = 6'd4;
598
        BPP12:  shifts = 6'd2;
599
        BPP16:  shifts = 6'd2;
600
        BPP20:  shifts = 6'd1;
601
        BPP32:  shifts = 6'd1;
602
        default:  shifts = 6'd2;
603
        endcase
604
default:
605
        begin
606
        $display("rtfBitmapController5: Bad master bus width");
607
        $finish;
608
        end
609 23 robfinch
endcase
610
 
611
wire vFetch = pixelRow < vDisplayed;
612
wire fifo_rrst = pixelCol==12'hFFF;
613
wire fifo_wrst = pe_hsync2;
614
 
615
wire[31:0] grAddr,xyAddr;
616
reg [11:0] fetchCol;
617 24 robfinch
localparam CMS = MDW==128 ? 6 : MDW==64 ? 5 : 4;
618
wire [CMS:0] mb,me,ce;
619
reg [MDW-1:0] mem_strip;
620
wire [MDW-1:0] mem_strip_o;
621 23 robfinch
wire [31:0] mem_color;
622
 
623 24 robfinch
gfx_CalcAddress6 #(MDW) u1
624 23 robfinch
(
625
  .clk(m_clk_i),
626
        .base_address_i(baseAddr),
627
        .color_depth_i(color_depth),
628
        .hdisplayed_i(hDisplayed),
629
        .x_coord_i(12'b0),
630
        .y_coord_i(pixelRow),
631
        .address_o(grAddr),
632
        .mb_o(),
633
        .me_o(),
634
        .ce_o()
635
);
636
 
637 24 robfinch
gfx_CalcAddress6 #(MDW) u2
638 23 robfinch
(
639
  .clk(m_clk_i),
640
        .base_address_i(baseAddr),
641
        .color_depth_i(color_depth),
642
        .hdisplayed_i(hDisplayed),
643
        .x_coord_i(px),
644
        .y_coord_i(py),
645
        .address_o(xyAddr),
646
        .mb_o(mb),
647
        .me_o(me),
648
        .ce_o(ce)
649
);
650
 
651
always @(posedge m_clk_i)
652
if (pe_hsync2)
653
  mapctr <= 12'hFFE;
654
else begin
655
  if (mapctr == map)
656
    mapctr <= 12'd0;
657
  else
658
    mapctr <= mapctr + 12'd1;
659
end
660
wire memreq = mapctr==12'd0;
661
 
662
// The following bypasses loading the fifo when all the pixels from a scanline
663
// are buffered in the fifo and the pixel row doesn't change. Since the fifo
664
// pointers are reset at the beginning of a scanline, the fifo can be used like
665
// a cache.
666
wire blankEdge;
667
edge_det ed2(.rst(rst_i), .clk(m_clk_i), .ce(1'b1), .i(blank_i), .pe(blankEdge), .ne(), .ee() );
668
reg do_loads;
669
reg [11:0] opixelRow;
670
reg load_fifo;
671
always @(posedge m_clk_i)
672
        //load_fifo <= fifo_cnt < 10'd1000 && vFetch && onoff && xonoff && !m_cyc_o && do_loads;
673
        load_fifo <= /*fifo_cnt < 8'd224 &&*/ vFetch && onoff && xonoff_i && fetchCol < hDisplayed && !m_cyc_o && do_loads && memreq;
674
// The following table indicates the number of pixel that will fit into the
675
// video fifo. 
676
reg [11:0] hCmp;
677
always @(color_depth)
678
case(color_depth)
679
BPP4: hCmp = 12'd4095;    // must be 12 bits
680
BPP8:   hCmp = 12'd2048;
681
BPP12: hCmp = 12'd1536;
682
BPP16:  hCmp = 12'd1024;
683
BPP20:  hCmp = 12'd768;
684
BPP32:  hCmp = 12'd512;
685
default:        hCmp = 12'd1024;
686
endcase
687
always @(posedge m_clk_i)
688
        // if hDisplayed > hCmp we always load because the fifo isn't large enough to act as a cache.
689
        if (!(hDisplayed < hCmp))
690
                do_loads <= 1'b1;
691
        // otherwise load the fifo only when the row changes to conserve memory bandwidth
692
        else if (vc==4'd1)//pixelRow != opixelRow)
693
                do_loads <= 1'b1;
694
        else if (blankEdge)
695
                do_loads <= 1'b0;
696
 
697
assign m_stb_o = m_cyc_o;
698 24 robfinch
assign m_sel_o = MDW==128 ? 16'hFFFF : MDW==64 ? 8'hFF : 4'hF;
699 23 robfinch
 
700
reg [31:0] adr;
701
reg [3:0] state;
702
reg [127:0] icolor1;
703
parameter IDLE = 4'd0;
704
parameter LOADCOLOR = 4'd2;
705
parameter LOADSTRIP = 4'd3;
706
parameter STORESTRIP = 4'd4;
707
parameter ACKSTRIP = 4'd5;
708
parameter WAITLOAD = 4'd6;
709
parameter WAITRST = 4'd7;
710
parameter ICOLOR1 = 4'd8;
711
parameter ICOLOR2 = 4'd9;
712
parameter ICOLOR3 = 4'd10;
713
parameter ICOLOR4 = 4'd11;
714
parameter WAIT_NACK = 4'd12;
715
 
716
function rastop;
717
input [3:0] op;
718
input a;
719
input b;
720
case(op)
721
OPBLACK: rastop = 1'b0;
722
OPCOPY:  rastop = b;
723
OPINV:   rastop = ~a;
724
OPAND:   rastop = a & b;
725
OPOR:    rastop = a | b;
726
OPXOR:   rastop = a ^ b;
727
OPANDN:  rastop = a & ~b;
728
OPNAND:  rastop = ~(a & b);
729
OPNOR:   rastop = ~(a | b);
730
OPXNOR:  rastop = ~(a ^ b);
731
OPORN:   rastop = a | ~b;
732
OPWHITE: rastop = 1'b1;
733 24 robfinch
default:        rastop = 1'b0;
734 23 robfinch
endcase
735
endfunction
736
 
737
always @(posedge m_clk_i)
738
        if (fifo_wrst)
739
                adr <= grAddr;
740
  else begin
741
    if (state==WAITLOAD && m_ack_i)
742
      adr <= adr + 32'd8;
743
  end
744
 
745
always @(posedge m_clk_i)
746
        if (fifo_wrst)
747
                fetchCol <= 12'd0;
748
  else begin
749
    if (state==WAITLOAD && m_ack_i)
750
      fetchCol <= fetchCol + shifts;
751
  end
752
 
753
always @(posedge m_clk_i)
754
if (rst_i) begin
755
        wb_nack();
756
  rstcmd <= 1'b0;
757
  state <= IDLE;
758
end
759
else begin
760
        case(state)
761
  WAITRST:
762
    if (pcmd==2'b00 && ~m_ack_i) begin
763
      rstcmd <= 1'b0;
764
      state <= IDLE;
765
    end
766
    else
767
      rstcmd <= 1'b1;
768
  IDLE:
769 24 robfinch
    if (load_fifo & ~m_ack_i) begin
770 23 robfinch
      m_cyc_o <= `HIGH;
771
      m_we_o <= `LOW;
772
      m_adr_o <= adr;
773
      state <= WAITLOAD;
774
    end
775
    // The adr_o[5:3]==3'b111 causes the controller to wait until all eight
776
    // 64 bit strips from the memory controller have been processed. Otherwise
777
    // there would be cache thrashing in the memory controller and the memory
778
    // bandwidth available would be greatly reduced. However fetches are also
779
    // allowed when loads are not active or all strips for the current scan-
780
    // line have been fetched.
781
    else if (pcmd!=2'b00 && (m_adr_o[5:3]==3'b111 || !(vFetch && onoff && xonoff_i && fetchCol < hDisplayed) || !do_loads)) begin
782
      m_cyc_o <= `HIGH;
783
      m_we_o <= `LOW;
784
      m_adr_o <= xyAddr;
785
      state <= LOADSTRIP;
786
    end
787
  LOADSTRIP:
788
    if (m_ack_i) begin
789
      wb_nack();
790
      mem_strip <= m_dat_i;
791 24 robfinch
      icolor1 <= {96'b0,color} << mb;
792 23 robfinch
      rstcmd <= 1'b1;
793
      if (pcmd==2'b01)
794
        state <= ICOLOR3;
795
      else if (pcmd==2'b10)
796
        state <= ICOLOR2;
797
      else begin
798
        state <= WAITRST;
799
      end
800
    end
801
  // Registered inline mem2color
802
  ICOLOR3:
803
    begin
804
      color_o <= mem_strip >> mb;
805
      state <= ICOLOR4;
806
    end
807
  ICOLOR4:
808
    begin
809
      for (n = 0; n < 32; n = n + 1)
810
        color_o[n] <= (n <= bpp) ? color_o[n] : 1'b0;
811
      state <= pcmd == 2'b0 ? (~m_ack_i ? IDLE : WAITRST) : WAITRST;
812
      if (pcmd==2'b00)
813
        rstcmd <= 1'b0;
814
    end
815
  // Registered inline color2mem
816
  ICOLOR2:
817
    begin
818 24 robfinch
      for (n = 0; n < MDW; n = n + 1)
819 23 robfinch
        m_dat_o[n] <= (n >= mb && n <= me)
820
                ? ((n <= ce) ?  rastop(raster_op, mem_strip[n], icolor1[n]) : icolor1[n])
821
                : mem_strip[n];
822
      state <= STORESTRIP;
823
    end
824
  STORESTRIP:
825
    if (~m_ack_i) begin
826
      m_cyc_o <= `HIGH;
827
      m_we_o <= `HIGH;
828
      state <= ACKSTRIP;
829
    end
830
  ACKSTRIP:
831
    if (m_ack_i) begin
832
      wb_nack();
833 24 robfinch
      state <= pcmd == 2'b0 ? IDLE : WAITRST;
834 23 robfinch
      if (pcmd==2'b00)
835
        rstcmd <= 1'b0;
836
    end
837
  WAITLOAD:
838
    if (m_ack_i) begin
839
      wb_nack();
840 24 robfinch
      state <= IDLE;
841
//      state <= WAIT_NACK;
842 23 robfinch
    end
843
  WAIT_NACK:
844
        if (~m_ack_i)
845
                state <= IDLE;
846
  default:      state <= IDLE;
847
  endcase
848
end
849
 
850
task wb_nack;
851
begin
852
        m_cyc_o <= `LOW;
853
        m_we_o <= `LOW;
854
end
855
endtask
856
 
857
reg [11:0] pixelColD1;
858
reg [31:0] rgbo2,rgbo4;
859 24 robfinch
reg [MDW-1:0] rgbo3;
860 23 robfinch
always @(posedge vclk)
861
case(color_depth)
862
BPP4:   rgbo4 <= {rgbo3[3],7'h00,21'd0,rgbo3[2:0]};      // feeds into palette
863
BPP8:   rgbo4 <= {rgbo3[7:6],6'h00,18'h0,rgbo3[5:0]};            // feeds into palette
864
BPP12:  rgbo4 <= {rgbo3[11:9],5'd0,rgbo3[8:6],5'd0,rgbo3[5:3],5'd0,rgbo3[2:0],5'd0};
865
BPP16:  rgbo4 <= {rgbo3[15:12],4'b0,rgbo3[11:8],4'b0,rgbo3[7:4],4'b0,rgbo3[3:0],4'b0};
866
BPP20:  rgbo4 <= {rgbo3[19:15],3'b0,rgbo3[14:10],4'b0,rgbo3[9:5],3'b0,rgbo3[4:0],3'b0};
867
BPP32:  rgbo4 <= rgbo3;
868
default:        rgbo4 <= {rgbo3[15:12],4'b0,rgbo3[11:8],4'b0,rgbo3[7:4],4'b0,rgbo3[3:0],4'b0};
869
endcase
870
 
871
reg rd_fifo,rd_fifo1,rd_fifo2;
872
reg de;
873
always @(posedge vclk)
874
        if (rd_fifo1)
875
                de <= ~blank_i;
876
 
877
always @(posedge vclk)
878
        if (onoff && xonoff_i && !blank_i) begin
879
                if (color_depth[2:1]==2'b00) begin
880
                        if (!greyscale)
881
                                zrgb_o <= pal_o[31:0];
882
                        else
883
                                zrgb_o <= {pal_o[31:24],{3{pal_o[7:0]}}};
884
                end
885
                else
886
                        zrgb_o <= rgbo4;
887
        end
888
        else
889
                zrgb_o <= 32'd0;
890
 
891
// Before the hrefdelay expires, pixelCol will be negative, which is greater
892
// than hDisplayed as the value is unsigned. That means that fifo reading is
893
// active only during the display area 0 to hDisplayed.
894
wire shift1 = hc==hres;
895 24 robfinch
reg [5:0] shift_cnt;
896 23 robfinch
always @(posedge vclk)
897
if (pe_hsync)
898
        shift_cnt <= 5'd1;
899
else begin
900
        if (shift1) begin
901
                if (pixelCol==12'hFFF)
902
                        shift_cnt <= shifts;
903
                else if (!pixelCol[11]) begin
904
                        shift_cnt <= shift_cnt + 5'd1;
905
                        if (shift_cnt==shifts)
906
                                shift_cnt <= 5'd1;
907
                end
908
                else
909
                        shift_cnt <= 5'd1;
910
        end
911
end
912
 
913
wire next_strip = (shift_cnt==shifts) && (hc==hres);
914
 
915
wire vrd;
916
always @(posedge vclk) pixelColD1 <= pixelCol;
917
reg shift,shift2;
918
always @(posedge vclk) shift2 <= shift1;
919
always @(posedge vclk) shift <= shift2;
920
always @(posedge vclk) rd_fifo2 <= next_strip;
921
always @(posedge vclk) rd_fifo <= rd_fifo2;
922
always @(posedge vclk)
923
        if (rd_fifo)
924
                rgbo3 <= rgbo1;
925
        else if (shift) begin
926
                case(color_depth)
927 24 robfinch
                BPP4:   rgbo3 <= {4'h0,rgbo3[MDW-1:4]};
928
                BPP8:   rgbo3 <= {8'h0,rgbo3[MDW-1:8]};
929
                BPP12: rgbo3 <= {12'h0,rgbo3[MDW-1:12]};
930
                BPP16:  rgbo3 <= {16'h0,rgbo3[MDW-1:16]};
931
                BPP20:  rgbo3 <= {20'h0,rgbo3[MDW-1:20]};
932
                BPP32:  rgbo3 <= {32'h0,rgbo3[MDW-1:32]};
933
                default: rgbo3 <= {16'h0,rgbo3[MDW-1:16]};
934 23 robfinch
                endcase
935
        end
936
 
937
 
938
/* Debugging
939
wire [127:0] dat;
940
assign dat[11:0] = pixelRow[0] ? 12'hEA4 : 12'h000;
941
assign dat[23:12] = pixelRow[1] ? 12'hEA4 : 12'h000;
942
assign dat[35:24] = pixelRow[2] ? 12'hEA4 : 12'h000;
943
assign dat[47:36] = pixelRow[3] ? 12'hEA4 : 12'h000;
944
assign dat[59:48] = pixelRow[4] ? 12'hEA4 : 12'h000;
945
assign dat[71:60] = pixelRow[5] ? 12'hEA4 : 12'h000;
946
assign dat[83:72] = pixelRow[6] ? 12'hEA4 : 12'h000;
947
assign dat[95:84] = pixelRow[7] ? 12'hEA4 : 12'h000;
948
assign dat[107:96] = pixelRow[8] ? 12'hEA4 : 12'h000;
949
assign dat[119:108] = pixelRow[9] ? 12'hEA4 : 12'h000;
950
*/
951
 
952 24 robfinch
rtfVideoFifo3 #(MDW) uf1
953 23 robfinch
(
954
        .wrst(fifo_wrst),
955
        .wclk(m_clk_i),
956
        .wr(m_ack_i && state==WAITLOAD),
957
        .di(m_dat_i),
958
        .rrst(fifo_rrst),
959
        .rclk(vclk),
960
        .rd(rd_fifo),
961
        .dout(rgbo1),
962
        .cnt(fifo_cnt)
963
);
964
 
965
endmodule

powered by: WebSVN 2.1.0

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