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

Subversion Repositories rtfbitmapcontroller

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

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

powered by: WebSVN 2.1.0

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