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

Subversion Repositories rtfbitmapcontroller

[/] [rtfbitmapcontroller/] [trunk/] [rtl/] [verilog/] [rtfBitmapController4.v] - Blame information for rev 20

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//  Bitmap Controller4
4
//  - Displays a bitmap from memory.
5
//
6
//
7
//        __
8
//   \\__/ o\    (C) 2008-2016  Robert Finch, Stratford
9
//    \  __ /    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
//              $0400000 - the second 4MiB of RAM
30
//
31
//
32
//      Verilog 1995
33
//
34
// ============================================================================
35
 
36
module rtfBitmapController4(
37
        rst_i,
38
        s_clk_i, s_cyc_i, s_stb_i, s_ack_o, s_we_i, s_adr_i, s_dat_i, s_dat_o, irq_o,
39
        m_clk_i, m_bte_o, m_cti_o, m_cyc_o, m_stb_o, m_ack_i, m_we_o, m_sel_o, m_adr_o, m_dat_i, m_dat_o,
40
        vclk, hsync, vsync, blank, rgbo, xonoff
41
);
42
parameter pIOAddress = 32'hFFDC5000;
43
parameter BM_BASE_ADDR1 = 32'h0040_0000;
44
parameter BM_BASE_ADDR2 = 32'h0050_0000;
45
parameter REG_CTRL = 10'd0;
46
parameter REG_CTRL2 = 10'd1;
47
parameter REG_HDISPLAYED = 10'd2;
48
parameter REG_VDISPLAYED = 10'd3;
49
parameter REG_PAGE1ADDR = 10'd5;
50
parameter REG_PAGE2ADDR = 10'd6;
51
parameter REG_REFDELAY = 10'd7;
52
parameter REG_MAP = 10'd8;
53
parameter REG_PX = 10'd9;
54
parameter REG_PY = 10'd10;
55
parameter REG_COLOR = 10'd11;
56
parameter REG_PCMD = 10'd12;
57
 
58 20 robfinch
parameter BPP6 = 3'd0;
59 18 robfinch
parameter BPP8 = 3'd1;
60
parameter BPP12 = 3'd2;
61
parameter BPP16 = 3'd3;
62
parameter BPP24 = 3'd4;
63
parameter BPP32 = 3'd5;
64
 
65
// SYSCON
66
input rst_i;                            // system reset
67
 
68
// Peripheral slave port
69
input s_clk_i;
70
input s_cyc_i;
71
input s_stb_i;
72
output s_ack_o;
73
input s_we_i;
74
input [31:0] s_adr_i;
75
input [31:0] s_dat_i;
76
output [31:0] s_dat_o;
77
reg [31:0] s_dat_o;
78
output irq_o;
79
 
80
// Video Master Port
81
// Used to read memory via burst access
82
input m_clk_i;                          // system bus interface clock
83
output [1:0] m_bte_o;
84
output [2:0] m_cti_o;
85
output m_cyc_o;                 // video burst request
86
output m_stb_o;
87
output reg m_we_o;
88
output [15:0] m_sel_o;
89
input  m_ack_i;                 // vid_acknowledge from memory
90
output [31:0] m_adr_o;   // address for memory access
91
input  [127:0] m_dat_i;  // memory data input
92
output reg [127:0] m_dat_o;
93
 
94
// Video
95
input vclk;                             // Video clock 85.71 MHz
96
input hsync;                            // start/end of scan line
97
input vsync;                            // start/end of frame
98
input blank;                    // blank the output
99
output [23:0] rgbo;              // 24-bit RGB output
100
reg [23:0] rgbo;
101
 
102
input xonoff;
103
 
104
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
105
// IO registers
106
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
107
reg m_cyc_o;
108
reg [31:0] m_adr_o;
109
 
110
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
111
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
112
wire cs = s_cyc_i && s_stb_i && (s_adr_i[31:12]==pIOAddress[31:12]);
113
reg ack,ack1;
114
always @(posedge s_clk_i)
115
begin
116
        ack1 <= cs;
117
        ack <= ack1 & cs;
118
end
119
assign s_ack_o = cs ? (s_we_i ? 1'b1 : ack) : 1'b0;
120
 
121
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
122
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
123
reg [11:0] hDisplayed,vDisplayed;
124
reg [31:0] bm_base_addr1,bm_base_addr2;
125
reg [2:0] color_depth;
126
wire [7:0] fifo_cnt;
127
reg onoff;
128
reg [2:0] hres,vres;
129
reg greyscale;
130
reg page;
131
reg pals;                               // palette select
132
reg [11:0] hrefdelay;
133
reg [11:0] vrefdelay;
134
reg [11:0] map;     // memory access period
135
reg [11:0] mapctr;
136
reg [11:0] hctr;         // horizontal reference counter
137
wire [11:0] hctr1 = hctr - hrefdelay;
138
reg [11:0] vctr;         // vertical reference counter
139
wire [11:0] vctr1 = vctr - vrefdelay;
140
reg [31:0] baseAddr;     // base address register
141
wire [127:0] rgbo1;
142
reg [11:0] pixelRow;
143
reg [11:0] pixelCol;
144
wire [31:0] pal_wo;
145
wire [31:0] pal_o;
146
reg [11:0] px;
147
reg [11:0] py;
148
reg [1:0] pcmd,pcmd_o;
149
reg [31:0] color;
150
reg [31:0] color_o;
151
reg rstcmd,rstcmd1;
152
 
153
always @(page or bm_base_addr1 or bm_base_addr2)
154
        baseAddr = page ? bm_base_addr2 : bm_base_addr1;
155
 
156
// Color palette RAM for 8bpp modes
157
syncRam512x32_1rw1r upal1
158
(
159
        .wrst(1'b0),
160
        .wclk(s_clk_i),
161
        .wce(cs & s_adr_i[11]),
162
        .we(s_we_i),
163
        .wadr(s_adr_i[10:2]),
164
        .i(s_dat_i),
165
        .wo(pal_wo),
166
        .rrst(1'b0),
167
        .rclk(vclk),
168
        .rce(1'b1),
169
        .radr({pals,rgbo4[7:0]}),
170
        .o(pal_o)
171
);
172
 
173
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
174
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
175
always @(posedge s_clk_i)
176
if (rst_i) begin
177
        page <= 1'b0;
178
        pals <= 1'b0;
179
        hres <= 3'd4;
180
        vres <= 3'd3;
181
        hDisplayed <= 12'd340;
182
        vDisplayed <= 12'd256;
183
        onoff <= 1'b1;
184
        color_depth <= BPP12;
185
        greyscale <= 1'b0;
186
        bm_base_addr1 <= BM_BASE_ADDR1;
187
        bm_base_addr2 <= BM_BASE_ADDR2;
188
        hrefdelay <= 12'd54;//12'd218;
189 20 robfinch
        vrefdelay <= 12'd18;//12'd27;
190 18 robfinch
        map <= 12'd0;
191
        pcmd <= 2'b00;
192
        rstcmd1 <= 1'b0;
193
end
194
else begin
195
        rstcmd1 <= rstcmd;
196
  if (rstcmd & ~rstcmd1)
197
    pcmd <= 2'b00;
198
        if (cs) begin
199
                if (s_we_i) begin
200
                        casex(s_adr_i[11:2])
201
                        REG_CTRL:
202
                                begin
203
                                        onoff <= s_dat_i[0];
204
                                        color_depth <= s_dat_i[10:8];
205
                                        greyscale <= s_dat_i[11];
206
                                        hres <= s_dat_i[18:16];
207
                                        vres <= s_dat_i[21:19];
208
                                end
209
                        REG_CTRL2:
210
                                begin
211
                                        page <= s_dat_i[16];
212
                                        pals <= s_dat_i[17];
213
                                end
214
                        REG_HDISPLAYED: hDisplayed <= s_dat_i[11:0];
215
                        REG_VDISPLAYED: vDisplayed <= s_dat_i[11:0];
216
                        REG_PAGE1ADDR:  bm_base_addr1 <= s_dat_i;
217
                        REG_PAGE2ADDR:  bm_base_addr2 <= s_dat_i;
218
                        REG_REFDELAY:
219
                                begin
220
                                        hrefdelay <= s_dat_i[11:0];
221
                                        vrefdelay <= s_dat_i[27:16];
222
                                end
223
                        REG_MAP:   map <= s_dat_i[11:0];
224
                        REG_PX:    px <= s_dat_i[11: 0];
225
                        REG_PY:    py <= s_dat_i[11:0];
226
                        REG_PCMD:  pcmd <= s_dat_i[1:0];
227
      REG_COLOR: color <= s_dat_i;
228
                        endcase
229
                end
230
                casex(s_adr_i[11:2])
231
                REG_CTRL:
232
                        begin
233
                                s_dat_o[0] <= onoff;
234
                                s_dat_o[10:8] <= color_depth;
235
                                s_dat_o[11] <= greyscale;
236
                                s_dat_o[18:16] <= hres;
237
                                s_dat_o[21:19] <= vres;
238
                        end
239
                REG_CTRL2:
240
                        begin
241
                                s_dat_o[16] <= page;
242
                                s_dat_o[17] <= pals;
243
                        end
244
                REG_HDISPLAYED: s_dat_o <= hDisplayed;
245
                REG_VDISPLAYED: s_dat_o <= vDisplayed;
246
                REG_PAGE1ADDR:  s_dat_o <= bm_base_addr1;
247
                REG_PAGE2ADDR:  s_dat_o <= bm_base_addr2;
248
                REG_REFDELAY:     s_dat_o <= {vrefdelay,4'h0,hrefdelay};
249
                REG_MAP:        s_dat_o <= map;
250
                REG_PX:                     s_dat_o <= px;
251
                REG_PY:                     s_dat_o <= py;
252
    REG_COLOR:      s_dat_o <= color_o;
253
                REG_PCMD:                         s_dat_o <= pcmd;
254
                10'b1xxx_xxxx_xx:        s_dat_o <= pal_wo;
255
                endcase
256
        end
257
        else
258
                s_dat_o <= 32'd0;
259
end
260
 
261
assign irq_o = 1'b0;
262
 
263
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
264
// Horizontal and Vertical timing reference counters
265
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
266
 
267 20 robfinch
wire pe_hsync, pe_hsync2;
268 18 robfinch
wire pe_vsync;
269
edge_det edh1
270
(
271
        .rst(rst_i),
272
        .clk(vclk),
273
        .ce(1'b1),
274
        .i(hsync),
275
        .pe(pe_hsync),
276
        .ne(),
277
        .ee()
278
);
279
 
280 20 robfinch
edge_det edh2
281
(
282
        .rst(rst_i),
283
        .clk(m_clk_i),
284
        .ce(1'b1),
285
        .i(hsync),
286
        .pe(pe_hsync2),
287
        .ne(),
288
        .ee()
289
);
290
 
291 18 robfinch
edge_det edv1
292
(
293
        .rst(rst_i),
294
        .clk(vclk),
295
        .ce(1'b1),
296
        .i(vsync),
297
        .pe(pe_vsync),
298
        .ne(),
299
        .ee()
300
);
301
 
302
reg [3:0] hc;
303
always @(posedge vclk)
304
if (rst_i)
305
        hc <= 4'd1;
306
else if (pe_hsync) begin
307
        hc <= 4'd1;
308
        pixelCol <= -hrefdelay;
309
end
310
else begin
311
        if (hc==hres) begin
312
                hc <= 4'd1;
313
                pixelCol <= pixelCol + 1;
314
        end
315
        else
316
                hc <= hc + 4'd1;
317
end
318
 
319
reg [3:0] vc;
320
always @(posedge vclk)
321
if (rst_i)
322
        vc <= 4'd1;
323
else if (pe_vsync) begin
324
        vc <= 4'd1;
325
        pixelRow <= -vrefdelay;
326
end
327
else begin
328
        if (pe_hsync) begin
329
                vc <= vc + 4'd1;
330
                if (vc==vres) begin
331
                        vc <= 4'd1;
332
                        pixelRow <= pixelRow + 1;
333
                end
334
        end
335
end
336
 
337
reg [4:0] shifts;
338
always @(color_depth)
339
case(color_depth)
340 20 robfinch
BPP6:   shifts = 5'd21;
341 18 robfinch
BPP8:   shifts = 5'd16;
342
BPP12:  shifts = 5'd10;
343
BPP16:  shifts = 5'd8;
344
BPP24:  shifts = 5'd5;
345
BPP32:  shifts = 5'd4;
346
default:  shifts = 5'd16;
347
endcase
348
 
349
wire vFetch = pixelRow < vDisplayed;
350
wire fifo_rrst = pixelCol==12'hFFF;
351 20 robfinch
wire fifo_wrst = pe_hsync2;
352 18 robfinch
 
353
wire[31:0] grAddr,xyAddr;
354
reg [11:0] fetchCol;
355
wire [6:0] mb,me;
356
reg [127:0] mem_strip;
357
wire [127:0] mem_strip_o;
358
wire [31:0] mem_color;
359
 
360
gfx_CalcAddress u1
361
(
362 20 robfinch
  .clk(vclk),
363 18 robfinch
        .base_address_i(baseAddr),
364 20 robfinch
        .color_depth_i({1'b0,color_depth}),
365 18 robfinch
        .hdisplayed_i(hDisplayed),
366
        .x_coord_i(0),
367
        .y_coord_i(pixelRow),
368
        .address_o(grAddr),
369
        .mb_o(),
370
        .me_o()
371
);
372
 
373
gfx_CalcAddress u2
374
(
375 20 robfinch
  .clk(vclk),
376 18 robfinch
        .base_address_i(baseAddr),
377 20 robfinch
        .color_depth_i({1'b0,color_depth}),
378 18 robfinch
        .hdisplayed_i(hDisplayed),
379
        .x_coord_i(px),
380
        .y_coord_i(py),
381
        .address_o(xyAddr),
382
        .mb_o(mb),
383
        .me_o(me)
384
);
385
 
386
mem2color u3
387
(
388
        .mem_i(mem_strip),
389
        .mb_i(mb),
390
        .me_i(me),
391
        .color_o(mem_color)
392
);
393
 
394
color2mem u4
395
(
396
        .mem_i(mem_strip),
397
        .mb_i(mb),
398
        .me_i(me),
399
        .color_i(color),
400
        .mem_o(mem_strip_o)
401
);
402
 
403
always @(posedge m_clk_i)
404 20 robfinch
if (pe_hsync2)
405 18 robfinch
  mapctr <= 12'hFFE;
406
else begin
407
  if (mapctr == map)
408
    mapctr <= 12'd0;
409
  else
410
    mapctr <= mapctr + 12'd1;
411
end
412
wire memreq = mapctr==12'd0;
413
 
414
// The following bypasses loading the fifo when all the pixels from a scanline
415
// are buffered in the fifo and the pixel row doesn't change. Since the fifo
416
// pointers are reset at the beginning of a scanline, the fifo can be used like
417
// a cache.
418
wire blankEdge;
419
edge_det ed2(.rst(rst_i), .clk(m_clk_i), .ce(1'b1), .i(blank), .pe(blankEdge), .ne(), .ee() );
420
reg do_loads;
421
reg [11:0] opixelRow;
422
reg load_fifo;
423
always @(posedge m_clk_i)
424
        //load_fifo <= fifo_cnt < 10'd1000 && vFetch && onoff && xonoff && !m_cyc_o && do_loads;
425 20 robfinch
        load_fifo <= /*fifo_cnt < 8'd224 &&*/ vFetch && onoff && xonoff && fetchCol < hDisplayed && !m_cyc_o && do_loads && memreq;
426
// The following table indicates the number of pixel that will fit into the
427
// video fifo. 
428 18 robfinch
reg [11:0] hCmp;
429
always @(color_depth)
430
case(color_depth)
431 20 robfinch
BPP6: hCmp = 12'd4095;
432
BPP8:   hCmp = 12'd4095;    // must be 12 bits
433 18 robfinch
BPP12:  hCmp = 12'd2559;
434
BPP16:  hCmp = 12'd2048;
435
BPP24:  hCmp = 12'd1279;
436
BPP32:  hCmp = 12'd1024;
437
default:        hCmp = 12'd1024;
438
endcase
439
always @(posedge m_clk_i)
440
        // if hDisplayed > hCmp we always load because the fifo isn't large enough to act as a cache.
441
        if (!(hDisplayed < hCmp))
442
                do_loads <= 1'b1;
443
        // otherwise load the fifo only when the row changes to conserve memory bandwidth
444 20 robfinch
        else if (vc==4'd1)//pixelRow != opixelRow)
445 18 robfinch
                do_loads <= 1'b1;
446
        else if (blankEdge)
447
                do_loads <= 1'b0;
448
 
449
assign m_bte_o = 2'b00;
450
assign m_cti_o = 3'b000;
451
assign m_stb_o = 1'b1;
452
assign m_sel_o = 16'hFFFF;
453
 
454
reg [31:0] adr;
455
reg [2:0] state;
456
parameter IDLE = 3'd1;
457
parameter LOADCOLOR = 3'd2;
458
parameter LOADSTRIP = 3'd3;
459
parameter STORESTRIP = 3'd4;
460
parameter ACKSTRIP = 3'd5;
461
parameter WAITLOAD = 3'd6;
462
parameter WAITRST = 3'd7;
463
 
464
reg [31:0] adr;
465
always @(posedge m_clk_i)
466 20 robfinch
        if (fifo_wrst)
467
                adr <= grAddr;
468
  else begin
469
    if (state==WAITLOAD && m_ack_i)
470
      adr <= adr + 32'd16;
471
  end
472
 
473
always @(posedge m_clk_i)
474
        if (fifo_wrst)
475
                fetchCol <= 12'd0;
476
  else begin
477
    if (state==WAITLOAD && m_ack_i)
478
      fetchCol <= fetchCol + shifts;
479
  end
480
 
481
always @(posedge m_clk_i)
482 18 robfinch
if (rst_i) begin
483
        wb_nack();
484
  rstcmd <= 1'b0;
485
  state <= IDLE;
486
end
487
else begin
488
        case(state)
489
  WAITRST:
490
    if (pcmd==2'b00) begin
491
      rstcmd <= 1'b0;
492
      state <= IDLE;
493
    end
494
    else
495
      rstcmd <= 1'b1;
496
  IDLE:
497
    if (load_fifo) begin
498
      m_cyc_o <= 1'b1;
499
      m_we_o <= 1'b0;
500
      m_adr_o <= adr;
501
      state <= WAITLOAD;
502
    end
503 20 robfinch
    // The adr_o[5:4]==2'b11 causes the controller to wait until all four
504 18 robfinch
    // 128 bit strips from the memory controller have been processed. Otherwise
505
    // there would be cache thrashing in the memory controller and the memory
506
    // bandwidth available would be greatly reduced. However fetches are also
507 20 robfinch
    // allowed when loads are not active or all strips for the current scan-
508 18 robfinch
    // line have been fetched.
509 20 robfinch
    else if (pcmd!=2'b00 && (m_adr_o[5:4]==2'b11 || !(vFetch && onoff && xonoff && fetchCol < hDisplayed) || !do_loads)) begin
510
      m_cyc_o <= 1'b1;
511
      m_we_o <= 1'b0;
512
      m_adr_o <= xyAddr;
513
      state <= LOADSTRIP;
514 18 robfinch
    end
515
  LOADCOLOR:
516
    begin
517
      color_o <= mem_color;
518
      rstcmd <= 1'b1;
519
      state <= WAITRST;
520
    end
521
  LOADSTRIP:
522
    if (m_ack_i) begin
523
      wb_nack();
524
      mem_strip <= m_dat_i;
525
      if (pcmd==2'b01)
526
        state <= LOADCOLOR;
527
      else if (pcmd==2'b10)
528
        state <= STORESTRIP;
529
      else begin
530
        rstcmd <= 1'b1;
531
        state <= WAITRST;
532
      end
533
    end
534
  STORESTRIP:
535
    begin
536
      rstcmd <= 1'b1;
537
      m_cyc_o <= 1'b1;
538
      m_we_o <= 1'b1;
539
      m_dat_o <= mem_strip_o;
540
      mem_strip <= mem_strip_o;
541
      state <= ACKSTRIP;
542
    end
543
  ACKSTRIP:
544
    if (m_ack_i) begin
545
      wb_nack();
546
      state <= WAITRST;
547
    end
548
  WAITLOAD:
549
    if (m_ack_i) begin
550
      wb_nack();
551
      state <= IDLE;
552
    end
553
  endcase
554
end
555
 
556
task wb_nack;
557
begin
558
        m_cyc_o <= 1'b0;
559
        m_we_o <= 1'b0;
560
end
561
endtask
562
 
563
reg [11:0] pixelColD1;
564
reg [23:0] rgbo2,rgbo4;
565
reg [127:0] rgbo3;
566
always @(posedge vclk)
567 20 robfinch
case(color_depth)
568
BPP6:   rgbo4 <= greyscale ? {3{rgbo3[5:0],2'b00}} : rgbo3[5:0];
569
BPP8:   rgbo4 <= greyscale ? {3{rgbo3[7:0]}} : rgbo3[7:0];
570
BPP12:  rgbo4 <= {rgbo3[11:8],4'h0,rgbo3[7:4],4'h0,rgbo3[3:0],4'h0};
571
BPP16:  rgbo4 <= {rgbo3[15:11],3'b0,rgbo3[10:5],2'b0,rgbo3[4:0],3'b0};
572
BPP24:  rgbo4 <= rgbo3[23:0];
573
BPP32:  rgbo4 <= rgbo3[23:0];
574
endcase
575 18 robfinch
 
576
reg rd_fifo,rd_fifo1,rd_fifo2;
577
reg de;
578
always @(posedge vclk)
579
        if (rd_fifo1)
580
                de <= ~blank;
581
 
582
always @(posedge vclk)
583
        if (onoff && xonoff && !blank) begin
584
                if (color_depth[2:1]==2'b00 && !greyscale)
585
                        rgbo <= pal_o;
586
                else
587
                        rgbo <= rgbo4[23:0];
588
        end
589
        else
590
                rgbo <= 24'd0;
591
 
592
// Before the hrefdelay expires, pixelCol will be negative, which is greater
593
// than hDisplayed as the value is unsigned. That means that fifo reading is
594
// active only during the display area 0 to hDisplayed.
595
wire shift1 = hc==hres;
596
reg [4:0] shift_cnt;
597
always @(posedge vclk)
598
if (pe_hsync)
599
        shift_cnt <= 5'd1;
600
else begin
601
        if (shift1) begin
602
                if (pixelCol==12'hFFF)
603
                        shift_cnt <= shifts;
604
                else if (!pixelCol[11]) begin
605
                        shift_cnt <= shift_cnt + 5'd1;
606
                        if (shift_cnt==shifts)
607
                                shift_cnt <= 5'd1;
608
                end
609
                else
610
                        shift_cnt <= 5'd1;
611
        end
612
end
613
 
614
wire next_strip = (shift_cnt==shifts) && (hc==hres);
615
 
616
wire vrd;
617
always @(posedge vclk) pixelColD1 <= pixelCol;
618
reg shift,shift2;
619
always @(posedge vclk) shift2 <= shift1;
620
always @(posedge vclk) shift <= shift2;
621
always @(posedge vclk) rd_fifo2 <= next_strip;
622
always @(posedge vclk) rd_fifo <= rd_fifo2;
623
always @(posedge vclk)
624
        if (rd_fifo)
625
                rgbo3 <= rgbo1;
626
        else if (shift) begin
627
                case(color_depth)
628 20 robfinch
                BPP6:   rgbo3 <= {rgbo3[127:6]};
629 18 robfinch
                BPP8:   rgbo3 <= {rgbo3[127:8]};
630
                BPP12:  rgbo3 <= {rgbo3[127:12]};
631
                BPP16:  rgbo3 <= {rgbo3[127:16]};
632
                BPP24:  rgbo3 <= {rgbo3[127:24]};
633
                BPP32:  rgbo3 <= {rgbo3[127:32]};
634
                endcase
635
        end
636
 
637
 
638 20 robfinch
/* Debugging
639
wire [127:0] dat;
640
assign dat[11:0] = pixelRow[0] ? 12'hEA4 : 12'h000;
641
assign dat[23:12] = pixelRow[1] ? 12'hEA4 : 12'h000;
642
assign dat[35:24] = pixelRow[2] ? 12'hEA4 : 12'h000;
643
assign dat[47:36] = pixelRow[3] ? 12'hEA4 : 12'h000;
644
assign dat[59:48] = pixelRow[4] ? 12'hEA4 : 12'h000;
645
assign dat[71:60] = pixelRow[5] ? 12'hEA4 : 12'h000;
646
assign dat[83:72] = pixelRow[6] ? 12'hEA4 : 12'h000;
647
assign dat[95:84] = pixelRow[7] ? 12'hEA4 : 12'h000;
648
assign dat[107:96] = pixelRow[8] ? 12'hEA4 : 12'h000;
649
assign dat[119:108] = pixelRow[9] ? 12'hEA4 : 12'h000;
650
*/
651
 
652 18 robfinch
rtfVideoFifo3 uf1
653
(
654
        .wrst(fifo_wrst),
655
        .wclk(m_clk_i),
656 20 robfinch
        .wr(m_ack_i && state==WAITLOAD),
657 18 robfinch
        .di(m_dat_i),
658
        .rrst(fifo_rrst),
659
        .rclk(vclk),
660
        .rd(rd_fifo),
661
        .dout(rgbo1),
662
        .cnt(fifo_cnt)
663
);
664
 
665
endmodule
666
 
667
// do a bitfield extract of color data
668
module mem2color(mem_i, mb_i, me_i, color_o);
669
 
670
input  [127:0] mem_i;
671
input [6:0] mb_i;
672
input [6:0] me_i;
673
output reg [31:0] color_o;
674
 
675
reg [127:0] mask;
676
reg [127:0] o1;
677
integer nn,n;
678
always @(mb_i or me_i or nn)
679
        for (nn = 0; nn < 128; nn = nn + 1)
680 20 robfinch
                mask[nn] <= (nn >= mb_i) & (nn <= me_i);
681 18 robfinch
always @*
682
begin
683
        for (n = 0; n < 128; n = n + 1)
684
                o1[n] = mask[n] ? mem_i[n] : 1'b0;
685
        color_o <= o1 >> mb_i;
686
end
687
 
688
endmodule
689
 
690
module color2mem(mem_i, mb_i, me_i, color_i, mem_o);
691
input [127:0] mem_i;
692
input [6:0] mb_i;
693
input [6:0] me_i;
694
input [31:0] color_i;
695
output reg [127:0] mem_o;
696
 
697
reg [127:0] o2;
698
reg [127:0] mask;
699
integer nn,n;
700
always @(mb_i or me_i or nn)
701
        for (nn = 0; nn < 128; nn = nn + 1)
702 20 robfinch
                mask[nn] <= (nn >= mb_i) & (nn <= me_i);
703 18 robfinch
 
704
always @*
705
begin
706
        o2 = color_i << mb_i;
707
        for (n = 0; n < 128; n = n + 1) mem_o[n] = (mask[n] ? o2[n] : mem_i[n]);
708
end
709
 
710
endmodule

powered by: WebSVN 2.1.0

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