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

Subversion Repositories rtf_sprite_controller

[/] [rtf_sprite_controller/] [trunk/] [rtl/] [verilog/] [rfSpriteController.sv] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2005-2022  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch@finitron.ca
7
//       ||
8
//
9
//      rfSpriteController.sv
10
//              sprite / hardware cursor controller
11
//
12
// BSD 3-Clause License
13
// Redistribution and use in source and binary forms, with or without
14
// modification, are permitted provided that the following conditions are met:
15
//
16
// 1. Redistributions of source code must retain the above copyright notice, this
17
//    list of conditions and the following disclaimer.
18
//
19
// 2. Redistributions in binary form must reproduce the above copyright notice,
20
//    this list of conditions and the following disclaimer in the documentation
21
//    and/or other materials provided with the distribution.
22
//
23
// 3. Neither the name of the copyright holder nor the names of its
24
//    contributors may be used to endorse or promote products derived from
25
//    this software without specific prior written permission.
26
//
27
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
31
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
//
38
//
39
//      Sprite Controller
40
//
41
//      FEATURES
42
//      - parameterized number of sprites 1,2,4,6,8,14,16 or 32
43
//      - sprite image cache buffers
44
//              - each image cache is capable of holding multiple
45
//                sprite images
46
//              - an embedded DMA controller is used for sprite reload
47
//      - programmable image offset within cache
48
//      - programmable sprite width,height, and pixel size
49
//              - sprite width and height may vary from 1 to 256 as long
50
//                as the product doesn't exceed 4096.
51
//          - pixels may be programmed to be 1,2,3 or 4 video clocks
52
//            both height and width are programmable
53
//      - programmable sprite position
54
//      - programmable 8, 16 or 32 bits for color
55
//              eg 32k color + 1 bit alpha blending indicator (1,5,5,5)
56
//      - fixed display and DMA priority
57
//          sprite 0 highest, sprite 31 lowest
58
//      - graphics plane control
59
//
60
//              This core requires an external timing generator to
61
//      provide horizontal and vertical sync signals, but
62
//      otherwise can be used as a display controller on it's
63
//      own. However, normally this core would be embedded
64
//      within another core such as a VGA controller. Sprite
65
//      positions are referenced to the rising edge of the
66
//      vertical and horizontal sync pulses.
67
//              The core includes an embedded dual port RAM to hold the
68
//      sprite images. The image RAM is updated using a built in DMA
69
//      controller. The DMA controller uses 32 bit accesses to fill
70
//      the sprite buffers. The circuit features an automatic bus
71
//  transaction timeout; if the system bus hasn't responded
72
//  within 20 clock cycles, the DMA controller moves onto the
73
//  next address.
74
//              The controller uses a ram underlay to cache the values
75
//      of the registers. This is a lot cheaper resource wise than
76
//      using a 32 to 1 multiplexor (well at least for an FPGA).
77
//
78
//      All registers are 32 bits wide
79
//
80
//      These registers repeat in incrementing block of four registers
81
//      and pertain to each sprite
82
//      00:     - position register
83
//              HPOS    [11: 0] horizontal position (hctr value)
84
//          VPOS        [27:16] vertical position (vctr value)
85
//
86
//      04:     SZ      - size register
87
//                      bits
88
//                      [ 7: 0] width of sprite in pixels - 1
89
//                      [15: 8] height of sprite in pixels -1
90
//                      [19:16] size of horizontal pixels - 1 in clock cycles
91
//                      [23:20] size of vertical pixels in scan-lines - 1
92
//                              * the product of width * height cannot exceed 2048 !
93
//                              if it does, the display will begin repeating
94
//                      [27:24] output plane
95
//                      [31:30] color depth 01=RGB332,10=RGB555+A,11=RGB888+A
96
//
97
//      08: ADR [31:12] 20 bits sprite image address bits
98
//                      This registers contain the high order address bits of the
99
//          location of the sprite image in system memory.
100
//                      The DMA controller will assign the low order 12 bits
101
//                      during DMA.
102
//                  [11:0] image offset bits [11:0]
103
//                      offset of the sprite image within the sprite image cache
104
//                      typically zero
105
//
106
//      0C: TC  [23:0]  transparent color
107
//                      This register identifies which color of the sprite
108
//                      is transparent
109
//
110
//
111
//
112
//      0C-1FC: registers reserved for up to thirty-one other sprites
113
//
114
//      200:            DMA burst reg sprite 0
115
//                              [8:0]  burst start
116
//                              [24:16] burst end
117
//      ...
118
//      27C:            DMA burst reg sprite 31
119
//
120
//  280:        [ 7: 0] Frame size, multiples of 16 pixels
121
//                              [15: 8] Number of frames of animation
122
//        [25:16] Animation Rate
123
//                              [29:26] Frame size, LSBs 0 to 3
124
//                              [30]            Auto repeat
125
//                              [31]    Enable animation
126
//  ...
127
//      2FC:    Animation register sprite #31
128
//
129
//      Global status and control
130
//      3C0: EN [31:0] sprite enable register
131
//  3C4: IE     [31:0] sprite interrupt enable / status
132
//      3C8: SCOL       [31:0] sprite-sprite collision register
133
//      3CC: BCOL       [31:0] sprite-background collision register
134
//      3D0: DT         [31:0] sprite DMA trigger on
135
//      3D4: DT         [31:0] sprite DMA trigger off
136
//      3D8: VDT        [31:0] sprite vertical sync DMA trigger
137
//      3EC: BC   [29:0] background color
138
//  3FC: ADDR   [31:0] sprite DMA address bits [63:32]
139
//
140 9 robfinch
// 7200
141 7 robfinch
//=============================================================================
142
 
143
import wishbone_pkg::*;
144
 
145
module rfSpriteController(
146
// Bus Slave interface
147
//------------------------------
148
// Slave signals
149
input rst_i,                    // reset
150
input s_clk_i,          // clock
151
input s_cs_i,
152
input   wb_write_request32_t wbs_req,
153
output wb_read_response32_t wbs_resp,
154
//------------------------------
155
// Bus Master Signals
156
input m_clk_i,                          // clock
157
output wb_write_request128_t wbm_req,
158
input wb_read_response128_t wbm_resp,
159
output [4:0] m_spriteno_o,
160
//--------------------------
161
input dot_clk_i,                // video dot clock
162
input hsync_i,                  // horizontal sync pulse
163
input vsync_i,                  // vertical sync pulse
164
input blank_i,                  // blanking signal
165
input [39:0] zrgb_i,                    // input pixel stream
166
output [39:0] zrgb_o,   // output pixel stream 12-12-12-4
167
output irq,                                     // interrupt request
168
input test,
169
input xonoff_i
170
);
171
 
172
reg m_soc_o;
173
wire vclk = dot_clk_i;
174
wire hSync = hsync_i;
175
wire vSync = vsync_i;
176
reg [39:0] zrgb_o;
177
 
178
//--------------------------------------------------------------------
179
// Core Parameters
180
//--------------------------------------------------------------------
181
parameter pnSpr = 32;           // number of sprites
182
parameter phBits = 12;          // number of bits in horizontal timing counter
183
parameter pvBits = 12;          // number of bits in vertical timing counter
184
localparam pnSprm = pnSpr-1;
185
 
186
 
187
//--------------------------------------------------------------------
188
// Variable Declarations
189
//--------------------------------------------------------------------
190
 
191
reg ce;                                                                         // controller enable
192
wb_write_request32_t wb_reqs;   // synchronized request
193
 
194
wire [4:0] sprN = wb_reqs.adr[8:4];
195
 
196
reg [phBits-1:0] hctr;          // horizontal reference counter (counts dots since hSync)
197
reg [pvBits-1:0] vctr;          // vertical reference counter (counts scanlines since vSync)
198
reg sprSprIRQ;
199
reg sprBkIRQ;
200
 
201
reg [31:0] out;                 // sprite output
202
reg outact;                             // sprite output is active
203
reg [3:0] outplane;
204
reg [pnSprm:0] bkCollision;             // sprite-background collision
205
reg [29:0] bgTc;                        // background transparent color
206
reg [29:0] bkColor;             // background color
207
 
208
 
209
reg [pnSprm:0] sprWe;   // block ram write enable for image cache update
210
reg [pnSprm:0] sprRe;   // block ram read enable for image cache update
211
 
212
// Global control registers
213
reg [31:0] sprEn;       // enable sprite
214
reg [pnSprm:0] sprCollision;        // sprite-sprite collision
215
reg sprSprIe;                   // sprite-sprite interrupt enable
216
reg sprBkIe;            // sprite-background interrupt enable
217
reg sprSprIRQPending;   // sprite-sprite collision interrupt pending
218
reg sprBkIRQPending;    // sprite-background collision interrupt pending
219
reg sprSprIRQPending1;  // sprite-sprite collision interrupt pending
220
reg sprBkIRQPending1;   // sprite-background collision interrupt pending
221
reg sprSprIRQ1;                 // vclk domain regs
222
reg sprBkIRQ1;
223
 
224
// Sprite control registers
225
reg [31:0] sprSprCollision;
226
reg [pnSprm:0] sprSprCollision1;
227
reg [31:0] sprBkCollision;
228
reg [pnSprm:0] sprBkCollision1;
229
reg [23:0] sprTc [pnSprm:0];            // sprite transparent color code
230
// How big the pixels are:
231
// 1 to 16 video clocks
232
reg [3:0] hSprRes [pnSprm:0];           // sprite horizontal resolution
233
reg [3:0] vSprRes [pnSprm:0];           // sprite vertical resolution
234
reg [7:0] sprWidth [pnSprm:0];          // number of pixels in X direction
235
reg [7:0] sprHeight [pnSprm:0];         // number of vertical pixels
236
reg [3:0] sprPlane [pnSprm:0];          // output plane sprite is in
237
reg [1:0] sprColorDepth [pnSprm:0];
238
reg [1:0] colorBits;
239
// Sprite DMA control
240
reg [8:0] sprBurstStart [pnSprm:0];
241
reg [8:0] sprBurstEnd   [pnSprm:0];
242
reg [31:0] vSyncT;                                                              // DMA on vSync
243
 
244
// display and timing signals
245
reg [31:0] hSprReset;   // horizontal reset
246
reg [31:0] vSprReset;   // vertical reset
247
reg [31:0] hSprDe;              // sprite horizontal display enable
248
reg [31:0] vSprDe;              // sprite vertical display enable
249
reg [31:0] sprDe;                       // display enable
250
reg [phBits-1:0] hSprPos [pnSprm:0];    // sprite horizontal position
251
reg [pvBits-1:0] vSprPos [pnSprm:0];    // sprite vertical position
252
reg [7:0] hSprCnt [pnSprm:0];   // sprite horizontal display counter
253
reg [7:0] vSprCnt [pnSprm:0];   // vertical display counter
254
reg [11:0] sprImageOffs [pnSprm:0];     // offset within sprite memory
255
reg [12:0] sprAddr [pnSprm:0];  // index into sprite memory (pixel number)
256
reg [9:0] sprAddr1 [pnSprm:0];  // index into sprite memory
257
reg [2:0] sprAddr2 [pnSprm:0];  // index into sprite memory
258
reg [2:0] sprAddr3 [pnSprm:0];  // index into sprite memory
259
reg [2:0] sprAddr4 [pnSprm:0];  // index into sprite memory
260
reg [2:0] sprAddr5 [pnSprm:0];  // index into sprite memory
261
reg [11:0] sprAddrB [pnSprm:0]; // backup address cache for rescan
262
wire [31:0] sprOut4 [pnSprm:0]; // sprite image data output
263
reg [31:0] sprOut [pnSprm:0];   // sprite image data output
264
reg [31:0] sprOut5 [pnSprm:0];  // sprite image data output
265 9 robfinch
wire [5:0] actcnt;      // count of sprites active at a given pixel location of the screen
266 7 robfinch
 
267
// Animation
268
reg [11:0] sprFrameSize [pnSprm:0];
269
reg [7:0] sprFrames [pnSprm:0];
270
reg [7:0] sprCurFrame [pnSprm:0];
271
reg [9:0] sprRate [pnSprm:0];
272
reg [9:0] sprCurRateCount [pnSprm:0];
273
reg [pnSprm:0] sprEnableAnimation;
274
reg [pnSprm:0] sprAutoRepeat;
275 9 robfinch
reg [11:0] sprFrameProd [pnSprm:0];
276 7 robfinch
 
277
// DMA access
278
reg [31:12] sprSysAddr [pnSprm:0];      // system memory address of sprite image (low bits)
279
reg [4:0] dmaOwner;                     // which sprite has the DMA channel
280
reg [31:0] sprDt;               // DMA trigger register
281
reg dmaActive;                          // this flag indicates that a block DMA transfer is active
282
 
283
genvar g;
284
 
285
//--------------------------------------------------------------------
286
// DMA control / bus interfacing
287
//--------------------------------------------------------------------
288
reg cs_regs;
289
always_ff @(posedge s_clk_i)
290
        cs_regs <= wbs_req.cyc & wbs_req.stb & s_cs_i;
291
always_ff @(posedge s_clk_i)
292
        wb_reqs <= wbs_req;
293
 
294
wire s_ack_o;
295
ack_gen #(
296
        .READ_STAGES(3),
297
        .WRITE_STAGES(1),
298
        .REGISTER_OUTPUT(1)
299
)
300
uag1 (
301
        .clk_i(s_clk_i),
302
        .ce_i(1'b1),
303
        .i(cs_regs),
304
        .we_i(cs_regs & wb_reqs.we),
305
        .o(s_ack_o),
306
        .rid_i(0),
307
        .wid_i(0),
308
        .rid_o(),
309
        .wid_o()
310
);
311
always_comb
312
begin
313
        wbs_resp.ack = s_ack_o & wbs_req.cyc & wbs_req.stb;
314
        wbs_resp.next = s_ack_o & wbs_req.cyc & wbs_req.stb;
315
end
316
 
317
assign irq = sprSprIRQ|sprBkIRQ;
318
 
319
//--------------------------------------------------------------------
320
// DMA control / bus interfacing
321
//--------------------------------------------------------------------
322
 
323
reg [5:0] dmaStart;
324
reg [8:0] cob;  // count of burst cycles
325
 
326
assign wbm_req.bte = LINEAR;
327
assign wbm_req.cti = CLASSIC;
328 9 robfinch
assign wbm_req.blen = 6'd63;
329 7 robfinch
assign wbm_req.stb = wbm_req.cyc;
330
assign wbm_req.sel = 16'hFFFF;
331
assign wbm_req.cid = 4'd5;
332
assign m_spriteno_o = dmaOwner;
333
 
334
reg [2:0] mstate;
335
parameter IDLE = 3'd0;
336
parameter ACTIVE = 3'd1;
337
parameter ACK = 3'd2;
338
parameter NACK = 3'd3;
339
 
340
wire pe_m_ack_i;
341
edge_det ued2 (.rst(rst_i), .clk(m_clk_i), .ce(1'b1), .i(wbm_resp.ack), .pe(pe_m_ack_i), .ne(), .ee());
342
 
343 9 robfinch
reg [11:0] tocnt;
344 7 robfinch
always_ff @(posedge m_clk_i)
345
if (rst_i)
346 9 robfinch
        tocnt <= 'd0;
347
else begin
348
        if (wbm_req.cyc)
349
                tocnt <= tocnt + 2'd1;
350
        else
351
                tocnt <= 'd0;
352
end
353
 
354
always_ff @(posedge m_clk_i)
355
if (rst_i)
356 7 robfinch
        mstate <= IDLE;
357
else begin
358
        case(mstate)
359
        IDLE:
360
                if (|sprDt & ce)
361
                        mstate <= ACTIVE;
362
        ACTIVE:
363
                mstate <= ACK;
364
        ACK:
365 9 robfinch
                if (wbm_resp.ack | wbm_resp.err | tocnt[10])
366 7 robfinch
                        mstate <= NACK;
367
        NACK:
368
                if (~(wbm_resp.ack|wbm_resp.err))
369
                        mstate <= cob==sprBurstEnd[dmaOwner] ? IDLE : ACTIVE;
370
        default:
371
                mstate <= IDLE;
372
        endcase
373
end
374
 
375
integer n30;
376
always_ff @(posedge m_clk_i)
377
begin
378
        case(mstate)
379
        IDLE:
380
                begin
381
                        dmaOwner <= 5'd0;
382
                        for (n30 = pnSprm; n30 >= 0; n30 = n30 - 1)
383
                                if (sprDt[n30])
384
                                        dmaOwner <= n30;
385
                end
386
        default:        ;
387
        endcase
388
end
389
 
390
always_ff @(posedge m_clk_i)
391
if (rst_i)
392
        dmaStart <= 6'b0;
393
else begin
394
        dmaStart <= {dmaStart[4:0],1'b0};
395
        case(mstate)
396
        IDLE:
397
                if (|sprDt & ce)
398
                        dmaStart <= 6'h3F;
399
        default:        ;
400
        endcase
401
end
402
 
403
integer n32;
404
always_ff @(posedge m_clk_i)
405
begin
406
        case(mstate)
407
        IDLE:
408
                for (n32 = pnSprm; n32 >= 0; n32 = n32 - 1)
409 9 robfinch
                        if (sprDt[n32] & ce)
410 7 robfinch
                                cob <= sprBurstStart[n32];
411
        ACTIVE:
412
                cob <= cob + 2'd2;
413
        default:        ;
414
        endcase
415
end
416
 
417
always_ff @(posedge m_clk_i)
418
if (rst_i)
419
        wb_m_nack();
420
else begin
421
        case(mstate)
422
        IDLE:
423
                wb_m_nack();
424
        ACTIVE:
425
                begin
426
                        wbm_req.cyc <= 1'b1;
427
                        wbm_req.adr <= {sprSysAddr[dmaOwner],cob[8:1],4'h0};
428
                end
429
        ACK:
430 9 robfinch
                if (wbm_resp.ack|wbm_resp.err|tocnt[10])
431 7 robfinch
                        wb_m_nack();
432
        endcase
433
end
434
 
435
task wb_m_nack;
436
begin
437
        wbm_req.cyc <= 1'b0;
438
end
439
endtask
440
 
441
 
442
// generate a write enable strobe for the sprite image memory
443
integer n1;
444 9 robfinch
reg [8:0] m_adr_or;             // 64-bit value address
445 7 robfinch
reg [127:0] m_dat_ir;
446
reg ack1;
447
 
448
always_ff @(posedge m_clk_i)
449
for (n1 = 0; n1 < pnSpr; n1 = n1 + 1)
450
        sprWe[n1] <= (dmaOwner==n1 && (pe_m_ack_i||ack1));
451
 
452
always_ff @(posedge m_clk_i)
453
        ack1 <= pe_m_ack_i;
454
always_ff @(posedge m_clk_i)
455
if (pe_m_ack_i|ack1)
456
        m_adr_or <= {wbm_req.adr[11:4],ack1};
457
always_ff @(posedge m_clk_i)
458
if (pe_m_ack_i) begin
459
        if (test)
460
                m_dat_ir <= {8{1'b0,dmaOwner,10'b0}};
461
        else
462
                m_dat_ir <= {wbm_resp.dat[63:0],wbm_resp.dat[127:64]};
463
end
464
else if (ack1)
465
        m_dat_ir <= {64'd0,m_dat_ir[127:64]};
466
 
467
 
468
//--------------------------------------------------------------------
469
//--------------------------------------------------------------------
470
 
471
reg [31:0] reg_shadow [0:255];
472
reg [7:0] radr;
473
always_ff @(posedge s_clk_i)
474
begin
475
    if (cs_regs & wb_reqs.we & wb_reqs.sel[0])  reg_shadow[wb_reqs.adr[9:2]][7:0] <= wb_reqs.dat[7:0];
476
    if (cs_regs & wb_reqs.we & wb_reqs.sel[1])  reg_shadow[wb_reqs.adr[9:2]][15:8] <= wb_reqs.dat[15:8];
477
    if (cs_regs & wb_reqs.we & wb_reqs.sel[2])  reg_shadow[wb_reqs.adr[9:2]][23:16] <= wb_reqs.dat[23:16];
478
    if (cs_regs & wb_reqs.we & wb_reqs.sel[3])  reg_shadow[wb_reqs.adr[9:2]][31:24] <= wb_reqs.dat[31:24];
479
end
480
always @(posedge s_clk_i)
481
  radr <= wb_reqs.adr[9:2];
482
wire [31:0] reg_shadow_o = reg_shadow[radr];
483
 
484
// register/sprite memory output mux
485
always_ff @(posedge s_clk_i)
486
        if (cs_regs)
487
                case (wb_reqs.adr[9:2])         // synopsys full_case parallel_case
488
                8'b11110000:    wbs_resp.dat <= sprEn;
489
                8'b11110001:    wbs_resp.dat <= {sprBkIRQPending|sprSprIRQPending,5'b0,sprBkIRQPending,sprSprIRQPending,6'b0,sprBkIe,sprSprIe};
490
                8'b11110010:    wbs_resp.dat <= sprSprCollision;
491
                8'b11110011:    wbs_resp.dat <= sprBkCollision;
492
                8'b11110100:    wbs_resp.dat <= sprDt;
493
                default:        wbs_resp.dat <= reg_shadow_o;
494
                endcase
495
        else
496
                wbs_resp.dat <= 32'h0;
497
 
498
 
499
// vclk -> clk_i
500
always @(posedge s_clk_i)
501
begin
502
        sprSprIRQ <= sprSprIRQ1;
503
        sprBkIRQ <= sprBkIRQ1;
504
        sprSprIRQPending <= sprSprIRQPending1;
505
        sprBkIRQPending <= sprBkIRQPending1;
506
        sprSprCollision <= sprSprCollision1;
507
        sprBkCollision <= sprBkCollision1;
508
end
509
 
510
 
511
// register updates
512
// on the clk_i domain
513
reg vSync1;
514
integer n33;
515
always_ff @(posedge s_clk_i)
516
if (rst_i) begin
517 9 robfinch
        vSyncT <= 32'hFFFFFFFF;//FFFFFFFF;
518 7 robfinch
        sprEn <= 32'hFFFFFFFF;
519
        sprDt <= 0;
520
  for (n33 = 0; n33 < pnSpr; n33 = n33 + 1) begin
521
                sprSysAddr[n33] <= 20'b0000_0000_0011_0000_0000 + n33;  //0030_0000
522
        end
523
        sprSprIe <= 0;
524
        sprBkIe  <= 0;
525
 
526
  // Set reasonable starting positions on the screen
527
  // so that the sprites might be visible for testing
528
  for (n33 = 0; n33 < pnSpr; n33 = n33 + 1) begin
529
    hSprPos[n33] <= 200 + (n33 & 7) * 70;
530
    vSprPos[n33] <= 100 + (n33 >> 3) * 100;
531
    sprTc[n33] <= 24'h7FFF;             // White 16 bpp
532 9 robfinch
                sprWidth[n33] <= 8'd24;         // 16x16 sprites
533
                sprHeight[n33] <= 8'd21;
534
                hSprRes[n33] <= 2'd2;   // our standard display
535
                vSprRes[n33] <= 2'd2;
536
                sprImageOffs[n33] <= 12'h0;
537
                sprPlane[n33] <= 4'h7;//n[3:0];
538 7 robfinch
                sprBurstStart[n33] <= 9'h000;
539
                sprBurstEnd[n33] <= 9'h1FE;
540
                sprColorDepth[n33] <= 2'b10;
541 9 robfinch
                if (n33 >= 5'd29) begin
542
                        sprFrameSize[n33] <= 12'd1936;
543
                        sprFrames[n33] <= 8'd0;
544
                end
545
                else begin
546
                        sprFrameSize[n33] <= 12'd504;
547
                        sprFrames[n33] <= 8'd3;
548
                end
549 7 robfinch
                sprRate[n33] <= 12'd10;
550 9 robfinch
                sprEnableAnimation[n33] <= n33 < 5'd29;
551 7 robfinch
                sprAutoRepeat[n33] <= 1'b1;
552
        end
553
  hSprPos[0] <= 210;
554
  vSprPos[0] <= 72;
555
 
556
  bgTc <= 24'h08_08_08;
557
  bkColor <= 24'hFF_FF_60;
558
end
559
else begin
560
        ce <= xonoff_i;
561
        vSync1 <= vSync;
562
        if (vSync & ~vSync1)
563
                sprDt <= sprDt | vSyncT;
564
 
565
        // clear DMA trigger bit once DMA is recognized
566
        if (dmaStart[5])
567
                sprDt[dmaOwner] <= 1'b0;
568
 
569
        // Disable animation after frame count expired, if not auto-repeat.
570
  for (n33 = 0; n33 < pnSpr; n33 = n33 + 1)
571
                if (sprCurFrame[n33] >= sprFrames[n33] && !sprAutoRepeat[n33])
572
                        sprEnableAnimation[n33] <= 1'b0;
573
 
574
        if (cs_regs & wb_reqs.we) begin
575
 
576
                casez (wb_reqs.adr[9:2])
577
                8'b100?????:
578
                        begin
579
                                if (&wb_reqs.sel[1:0]) sprBurstStart[wb_reqs.adr[6:2]] <= {wb_reqs.dat[8:1],1'b0};
580
                                if (&wb_reqs.sel[3:2]) sprBurstEnd[wb_reqs.adr[6:2]] <= {wb_reqs.dat[24:17],1'b0};
581
                        end
582
                8'b101?????:
583
                        begin
584
                                if (wb_reqs.sel[0]) sprFrameSize[wb_reqs.adr[6:2]][11:4] <= wb_reqs.dat[7:0];
585
                                if (wb_reqs.sel[1]) sprFrames[wb_reqs.adr[6:2]] <= wb_reqs.dat[15:8];
586
                                if (wb_reqs.sel[2]) sprRate[wb_reqs.adr[6:2]][7:0] <= wb_reqs.dat[23:16];
587
                                if (wb_reqs.sel[3])
588
                                        begin
589
                                                sprRate[wb_reqs.adr[6:2]][9:8] <= wb_reqs.dat[25:24];
590
                                                sprFrameSize[wb_reqs.adr[6:2]][3:0] <= wb_reqs.dat[29:26];
591
                                                sprAutoRepeat[wb_reqs.adr[6:2]] <= wb_reqs.dat[30];
592
                                                sprEnableAnimation[wb_reqs.adr[6:2]] <= wb_reqs.dat[31];
593
                                        end
594
                        end
595
                8'b11110000:    // 3C0
596
                        begin
597
                                if (wb_reqs.sel[0]) sprEn[7:0] <= wb_reqs.dat[7:0];
598
                                if (wb_reqs.sel[1]) sprEn[15:8] <= wb_reqs.dat[15:8];
599
                                if (wb_reqs.sel[2]) sprEn[23:16] <= wb_reqs.dat[23:16];
600
                                if (wb_reqs.sel[3]) sprEn[31:24] <= wb_reqs.dat[31:24];
601
                        end
602
                8'b11110001:    // 3C4
603
                        if (wb_reqs.sel[0]) begin
604
                                sprSprIe <= wb_reqs.dat[0];
605
                                sprBkIe <= wb_reqs.dat[1];
606
                        end
607
                // update DMA trigger
608
                // s_wb_reqs.dat[7:0] indicates which triggers to set  (1=set,0=ignore)
609
                // s_wb_reqs.dat[7:0] indicates which triggers to clear (1=clear,0=ignore)
610
                8'b11110100:    // 3D0
611
                        begin
612
                                if (wb_reqs.sel[0])     sprDt[7:0] <= sprDt[7:0] | wb_reqs.dat[7:0];
613
                                if (wb_reqs.sel[1]) sprDt[15:8] <= sprDt[15:8] | wb_reqs.dat[15:8];
614
                                if (wb_reqs.sel[2]) sprDt[23:16] <= sprDt[23:16] | wb_reqs.dat[23:16];
615
                                if (wb_reqs.sel[3])     sprDt[31:24] <= sprDt[31:24] | wb_reqs.dat[31:24];
616
                        end
617
                8'b11110101:    // 3D4
618
                        begin
619
                                if (wb_reqs.sel[0])     sprDt[7:0] <= sprDt[7:0] & ~wb_reqs.dat[7:0];
620
                                if (wb_reqs.sel[1]) sprDt[15:8] <= sprDt[15:8] & ~wb_reqs.dat[15:8];
621
                                if (wb_reqs.sel[2]) sprDt[23:16] <= sprDt[23:16] & ~wb_reqs.dat[23:16];
622
                                if (wb_reqs.sel[3])     sprDt[31:24] <= sprDt[31:24] & ~wb_reqs.dat[31:24];
623
                        end
624
                8'b11110110:    // 3D8
625
                        begin
626
                                if (wb_reqs.sel[0])     vSyncT[7:0] <= wb_reqs.dat[7:0];
627
                                if (wb_reqs.sel[1]) vSyncT[15:8] <= wb_reqs.dat[15:8];
628
                                if (wb_reqs.sel[2]) vSyncT[23:16] <= wb_reqs.dat[23:16];
629
                                if (wb_reqs.sel[3])     vSyncT[31:24] <= wb_reqs.dat[31:24];
630
                        end
631
                8'b11111010:    // 3E8
632
                        begin
633
                                if (wb_reqs.sel[0])     bgTc[7:0] <= wb_reqs.dat[7:0];
634
                                if (wb_reqs.sel[1])     bgTc[15:8] <= wb_reqs.dat[15:8];
635
                                if (wb_reqs.sel[2])     bgTc[23:16] <= wb_reqs.dat[23:16];
636
                                if (wb_reqs.sel[3])     bgTc[29:24] <= wb_reqs.dat[29:24];
637
                        end
638
                8'b11111011:    // 3EC
639
                        begin
640
                                if (wb_reqs.sel[0]) bkColor[7:0] <= wb_reqs.dat[7:0];
641
                                if (wb_reqs.sel[1]) bkColor[15:8] <= wb_reqs.dat[15:8];
642
                                if (wb_reqs.sel[2]) bkColor[23:16] <= wb_reqs.dat[23:16];
643
                                if (wb_reqs.sel[3]) bkColor[29:24] <= wb_reqs.dat[29:24];
644
                        end
645
//              8'b11111100:    // 3F0
646
//                      if (wb_reqs.sel[0]) ce <= wb_reqs[0];
647
                8'b0?????00:
648
                         begin
649
                        if (wb_reqs.sel[0]) hSprPos[sprN][ 7:0] <= wb_reqs.dat[ 7: 0];
650
                        if (wb_reqs.sel[1]) hSprPos[sprN][11:8] <= wb_reqs.dat[11: 8];
651
                        if (wb_reqs.sel[2]) vSprPos[sprN][ 7:0] <= wb_reqs.dat[23:16];
652
                        if (wb_reqs.sel[3]) vSprPos[sprN][11:8] <= wb_reqs.dat[27:24];
653
                end
654
    8'b0?????01:
655
                        begin
656
                if (wb_reqs.sel[0]) begin
657
                                        sprWidth[sprN] <= wb_reqs.dat[7:0];
658
        end
659
                if (wb_reqs.sel[1]) begin
660
                                        sprHeight[sprN] <= wb_reqs.dat[15:8];
661
        end
662
                                if (wb_reqs.sel[2]) begin
663
                hSprRes[sprN] <= wb_reqs.dat[19:16];
664
                vSprRes[sprN] <= wb_reqs.dat[23:20];
665
                                end
666
                                if (wb_reqs.sel[3]) begin
667
                                        sprPlane[sprN] <= wb_reqs.dat[27:24];
668
                                        sprColorDepth[sprN] <= wb_reqs.dat[31:30];
669
                                end
670
                        end
671
                8'b0?????10:
672
                        begin   // DMA address set on clk_i domain
673
        if (wb_reqs.sel[0]) sprImageOffs[sprN][ 7:0] <= wb_reqs.dat[7:0];
674
        if (wb_reqs.sel[1]) sprImageOffs[sprN][11:8] <= wb_reqs.dat[11:8];
675
                                if (wb_reqs.sel[1]) sprSysAddr[sprN][15:12] <= wb_reqs.dat[15:12];
676
                                if (wb_reqs.sel[2]) sprSysAddr[sprN][23:16] <= wb_reqs.dat[23:16];
677
                                if (wb_reqs.sel[3]) sprSysAddr[sprN][31:24] <= wb_reqs.dat[31:24];
678
                        end
679
                8'b0?????11:
680
                        begin
681
                                if (wb_reqs.sel[0]) sprTc[sprN][ 7:0] <= wb_reqs.dat[ 7:0];
682
                                if (wb_reqs.sel[1]) sprTc[sprN][15:8] <= wb_reqs.dat[15:8];
683
                                if (wb_reqs.sel[2]) sprTc[sprN][23:16] <= wb_reqs.dat[23:16];
684
                        end
685
 
686
                default:        ;
687
                endcase
688
 
689
        end
690
end
691
 
692
//-------------------------------------------------------------
693
// Sprite Image Cache RAM
694
// This RAM is dual ported with an SoC side and a display
695
// controller side.
696
//-------------------------------------------------------------
697
 
698
integer n2;
699
always_ff @(posedge vclk)
700
for (n2 = 0; n2 < pnSpr; n2 = n2 + 1)
701
case(sprColorDepth[n2])
702
2'd1:   sprAddr1[n2] <= {sprAddr[n2][11:3],~sprAddr[n2][2]};
703
2'd2:   sprAddr1[n2] <= {sprAddr[n2][10:2],~sprAddr[n2][1]};
704
2'd3:   sprAddr1[n2] <= {sprAddr[n2][ 9:1],~sprAddr[n2][0]};
705
default:        ;
706
endcase
707
 
708
// The three LSBs of the image index need to be pipelined so they may be used
709
// to select the pixel. Output from the SRAM is always 32-bits wide so an
710
// additional mux is needed.
711
integer n4, n5, n27, n29;
712
always_ff @(posedge vclk)
713
for (n4 = 0; n4 < pnSpr; n4 = n4 + 1)
714
        sprAddr2[n4] <= ~sprAddr[n4][2:0];
715
always_ff @(posedge vclk)
716
for (n5 = 0; n5 < pnSpr; n5 = n5 + 1)
717
        sprAddr3[n5] <= sprAddr2[n5];
718
always_ff @(posedge vclk)
719
for (n27 = 0; n27 < pnSpr; n27 = n27 + 1)
720
        sprAddr4[n27] <= sprAddr3[n27];
721
always_ff @(posedge vclk)
722
for (n29 = 0; n29 < pnSpr; n29 = n29 + 1)
723
        sprAddr5[n29] <= sprAddr4[n29];
724
 
725
// The pixels are displayed from most signicant to least signicant bits of the
726
// word. Display order is opposite to memory storage. So, the least significant
727
// address bits are flipped to get the correct display.
728
integer n3;
729
always_ff @(posedge vclk)
730
for (n3 = 0; n3 < pnSpr; n3 = n3 + 1)
731
case(sprColorDepth[n3])
732
2'd1:
733
        case(sprAddr5[n3][1:0])
734
        2'd3:   sprOut5[n3] <= sprOut4[n3][31:24];
735
        2'd2:   sprOut5[n3] <= sprOut4[n3][23:16];
736
        2'd1:   sprOut5[n3] <= sprOut4[n3][15:8];
737
        2'd0:   sprOut5[n3] <= sprOut4[n3][7:0];
738
        endcase
739
2'd2:
740
        case(sprAddr5[n3][0])
741
        1'd0:   sprOut5[n3] <= {sprOut4[n3][15],16'h0000,sprOut4[n3][14:0]};
742
        1'd1:   sprOut5[n3] <= {sprOut4[n3][31],16'h0000,sprOut4[n3][30:16]};
743
        endcase
744
2'd3:
745
        sprOut5[n3] <= sprOut4[n3];
746
default:        ;
747
endcase
748
 
749
generate
750
for (g = 0; g < pnSpr; g = g + 1) begin : sprRam
751
        SpriteRam sprRam0
752
        (
753
                .clka(m_clk_i),
754
                .addra(m_adr_or),
755
                .dina(m_dat_ir[63:0]),
756
                .ena(sprWe[g]),
757
                .wea(sprWe[g]),
758
                // Core reg and output reg 3 clocks from read address
759
                .clkb(vclk),
760
                .addrb(sprAddr1[g]),
761
                .doutb(sprOut4[g]),
762
                .enb(1'b1)
763
        );
764
        end
765
endgenerate
766
 
767
//-------------------------------------------------------------
768
// Timing counters and addressing
769
// Sprites are like miniature bitmapped displays, they need
770
// all the same timing controls.
771
//-------------------------------------------------------------
772
 
773
// Create a timing reference using horizontal and vertical
774
// sync
775
wire hSyncEdge, vSyncEdge;
776
edge_det ed0(.rst(rst_i), .clk(vclk), .ce(1'b1), .i(hSync), .pe(hSyncEdge), .ne(), .ee() );
777
edge_det ed1(.rst(rst_i), .clk(vclk), .ce(1'b1), .i(vSync), .pe(vSyncEdge), .ne(), .ee() );
778
 
779
always_ff @(posedge vclk)
780
if (hSyncEdge) hctr <= {phBits{1'b0}};
781
else hctr <= hctr + 2'd1;
782
 
783
always_ff @(posedge vclk)
784
if (vSyncEdge) vctr <= {pvBits{1'b0}};
785
else if (hSyncEdge) vctr <= vctr + 2'd1;
786
 
787
// track sprite horizontal reset
788
integer n19;
789
always_ff @(posedge vclk)
790
for (n19 = 0; n19 < pnSpr; n19 = n19 + 1)
791
        hSprReset[n19] <= hctr==hSprPos[n19];
792
 
793
// track sprite vertical reset
794
integer n20;
795
always_ff @(posedge vclk)
796
for (n20 = 0; n20 < pnSpr; n20 = n20 + 1)
797
        vSprReset[n20] <= vctr==vSprPos[n20];
798
 
799
integer n21;
800
always_comb
801
for (n21 = 0; n21 < pnSpr; n21 = n21 + 1)
802
        sprDe[n21] <= hSprDe[n21] & vSprDe[n21];
803
 
804
 
805
// take care of sprite size scaling
806
// video clock division
807
reg [31:0] hSprNextPixel;
808
reg [31:0] vSprNextPixel;
809
reg [3:0] hSprPt [31:0];   // horizontal pixel toggle
810
reg [3:0] vSprPt [31:0];   // vertical pixel toggle
811
integer n17;
812
always_comb
813
for (n17 = 0; n17 < pnSpr; n17 = n17 + 1)
814
    hSprNextPixel[n17] = hSprPt[n17]==hSprRes[n17];
815
integer n18;
816
always_comb
817
for (n18 = 0; n18 < pnSpr; n18 = n18 + 1)
818
    vSprNextPixel[n18] = vSprPt[n18]==vSprRes[n18];
819
 
820
// horizontal pixel toggle counter
821
integer n6;
822
always_ff @(posedge vclk)
823
for (n6 = 0; n6 < pnSpr; n6 = n6 + 1)
824
        if (hSprReset[n6])
825
                hSprPt[n6] <= 4'd0;
826
  else if (hSprNextPixel[n6])
827
    hSprPt[n6] <= 4'd0;
828
  else
829
    hSprPt[n6] <= hSprPt[n6] + 2'd1;
830
 
831
// vertical pixel toggle counter
832
integer n7;
833
always_ff @(posedge vclk)
834
for (n7 = 0; n7 < pnSpr; n7 = n7 + 1)
835
  if (hSprReset[n7]) begin
836
        if (vSprReset[n7])
837
                vSprPt[n7] <= 4'd0;
838
    else if (vSprNextPixel[n7])
839
      vSprPt[n7] <= 4'd0;
840
    else
841
      vSprPt[n7] <= vSprPt[n7] + 2'd1;
842
  end
843
 
844
// Animation rate count and frame increment.
845
integer n28;
846
always_ff @(posedge vclk)
847
        if (vSyncEdge) begin
848
                for (n28 = 0; n28 < pnSpr; n28 = n28 + 1) begin
849
                        if (sprEnableAnimation[n28]) begin
850
                                sprCurRateCount[n28] <= sprCurRateCount[n28] + 2'd1;
851
                                if (sprCurRateCount[n28] >= sprRate[n28]) begin
852
                                        sprCurRateCount[n28] <= 'd0;
853
                                        sprCurFrame[n28] <= sprCurFrame[n28] + 2'd1;
854 9 robfinch
                                        sprFrameProd[n28] <= sprFrameProd[n28] + sprFrameSize[n28];
855
                                        if (sprCurFrame[n28] >= sprFrames[n28]) begin
856 7 robfinch
                                                sprCurFrame[n28] <= 'd0;
857 9 robfinch
                                                sprFrameProd[n28] <= 'd0;
858
                                        end
859 7 robfinch
                                end
860
                        end
861 9 robfinch
                        else begin
862 7 robfinch
                                sprCurFrame[n28] <= 'd0;
863 9 robfinch
                                sprFrameProd[n28] <= 'd0;
864
                        end
865 7 robfinch
                end
866
        end
867 9 robfinch
 
868 7 robfinch
// clock sprite image address counters
869
integer n8;
870
always_ff @(posedge vclk)
871
for (n8 = 0; n8 < pnSpr; n8 = n8 + 1) begin
872
    // hReset and vReset - top left of sprite,
873
    // reset address to image offset
874
        if (hSprReset[n8] & vSprReset[n8]) begin
875 9 robfinch
                sprAddr[n8]  <= sprImageOffs[n8] + sprFrameProd[n8];
876
                sprAddrB[n8] <= sprImageOffs[n8] + sprFrameProd[n8];
877 7 robfinch
        end
878
        // hReset:
879
        //  If the next vertical pixel
880
        //      set backup address to current address
881
        //  else
882
        //      set current address to backup address
883
        //      in order to rescan the line
884
        else if (hSprReset[n8]) begin
885
                if (vSprNextPixel[n8])
886
                        sprAddrB[n8] <= sprAddr[n8];
887
                else
888
                        sprAddr[n8]  <= sprAddrB[n8];
889
        end
890
        // Not hReset or vReset - somewhere on the sprite scan line
891
        // just advance the address when the next pixel should be
892
        // fetched
893
        else if (hSprDe[n8] & hSprNextPixel[n8])
894
                sprAddr[n8] <= sprAddr[n8] + 2'd1;
895
end
896
 
897
 
898
// clock sprite column (X) counter
899
integer n9;
900
always_ff @(posedge vclk)
901
for (n9 = 0; n9 < pnSpr; n9 = n9 + 1)
902
        if (hSprReset[n9])
903
                hSprCnt[n9] <= 8'd1;
904
        else if (hSprNextPixel[n9])
905
                hSprCnt[n9] <= hSprCnt[n9] + 2'd1;
906
 
907
 
908
// clock sprite horizontal display enable
909
integer n10;
910
always_ff @(posedge vclk)
911
for (n10 = 0; n10 < pnSpr; n10 = n10 + 1) begin
912
        if (hSprReset[n10])
913
                hSprDe[n10] <= 1'b1;
914
        else if (hSprNextPixel[n10]) begin
915
                if (hSprCnt[n10] == sprWidth[n10])
916
                        hSprDe[n10] <= 1'b0;
917
        end
918
end
919
 
920
 
921
// clock the sprite row (Y) counter
922
integer n11;
923
always_ff @(posedge vclk)
924
for (n11 = 0; n11 < pnSpr; n11 = n11 + 1)
925
        if (hSprReset[n11]) begin
926
                if (vSprReset[n11])
927
                        vSprCnt[n11] <= 8'd1;
928
                else if (vSprNextPixel[n11])
929
                        vSprCnt[n11] <= vSprCnt[n11] + 2'd1;
930
        end
931
 
932
 
933
// clock sprite vertical display enable
934
integer n12;
935
always_ff @(posedge vclk)
936
for (n12 = 0; n12 < pnSpr; n12 = n12 + 1) begin
937
        if (hSprReset[n12]) begin
938
                if (vSprReset[n12])
939
                        vSprDe[n12] <= 1'b1;
940
                else if (vSprNextPixel[n12]) begin
941
                        if (vSprCnt[n12] == sprHeight[n12])
942
                                vSprDe[n12] <= 1'b0;
943
                end
944
        end
945
end
946
 
947
 
948
//-------------------------------------------------------------
949
// Output stage
950
//-------------------------------------------------------------
951
 
952
// function used for color blending
953
// given an alpha and a color component, determine the resulting color
954
// this blends towards black or white
955
// alpha is eight bits ranging between 0 and 1.999...
956
// 1 bit whole, 7 bits fraction
957
function [11:0] fnBlend;
958
input [7:0] alpha;
959
input [11:0] color1bits;
960
input [11:0] color2bits;
961
 
962
begin
963
        fnBlend = (({8'b0,color1bits} * alpha) >> 7) + (({8'h00,color2bits} * (9'h100 - alpha)) >> 7);
964
end
965
endfunction
966
 
967
 
968
// pipeline delays for display enable
969
reg [31:0] sprDe1, sprDe2, sprDe3, sprDe4, sprDe5, sprDe6;
970
reg [31:0] sproact;
971
integer n13;
972
always_ff @(posedge vclk)
973
for (n13 = 0; n13 < pnSpr; n13 = n13 + 1)
974
        sprDe1[n13] <= sprDe[n13];
975
integer n22;
976
always_ff @(posedge vclk)
977
for (n22 = 0; n22 < pnSpr; n22 = n22 + 1)
978
        sprDe2[n22] <= sprDe1[n22];
979
integer n23;
980
always_ff @(posedge vclk)
981
for (n23 = 0; n23 < pnSpr; n23 = n23 + 1)
982
        sprDe3[n23] <= sprDe2[n23];
983
integer n24;
984
always_ff @(posedge vclk)
985
for (n24 = 0; n24 < pnSpr; n24 = n24 + 1)
986
        sprDe4[n24] <= sprDe3[n24];
987
integer n25;
988
always_ff @(posedge vclk)
989
for (n25 = 0; n25 < pnSpr; n25 = n25 + 1)
990
        sprDe5[n25] <= sprDe4[n25];
991
integer n26;
992
always_ff @(posedge vclk)
993
for (n26 = 0; n26 < pnSpr; n26 = n26 + 1)
994
        sprDe6[n26] <= sprDe5[n26];
995
 
996
 
997
// Detect which sprite outputs are active
998
// The sprite output is active if the current display pixel
999
// address is within the sprite's area, the sprite is enabled,
1000
// and it's not a transparent pixel that's being displayed.
1001
integer n14;
1002
always_ff @(posedge vclk)
1003
for (n14 = 0; n14 < pnSpr; n14 = n14 + 1)
1004
        sproact[n14] <= sprEn[n14] && sprDe5[n14] && sprTc[n14]!=sprOut5[n14];
1005
integer n15;
1006
always_ff @(posedge vclk)
1007
for (n15 = 0; n15 < pnSpr; n15 = n15 + 1)
1008
        sprOut[n15] <= sprOut5[n15];
1009
 
1010
// register sprite activity flag
1011
// The image combiner uses this flag to know what to do with
1012
// the sprite output.
1013
always_ff @(posedge vclk)
1014
        outact <= |sproact & ce;
1015
 
1016
// Display data comes from the active sprite with the
1017
// highest display priority.
1018
// Make sure that alpha blending is turned off when
1019
// no sprite is active.
1020
integer n16;
1021
always_ff @(posedge vclk)
1022
begin
1023
        out <= 32'h0080;        // alpha blend max (and off)
1024
        outplane <= 4'h0;
1025
        colorBits <= 2'b00;
1026
        for (n16 = pnSprm; n16 >= 0; n16 = n16 - 1)
1027
                if (sproact[n16]) begin
1028
                        out <= sprOut[n16];
1029
                        outplane <= sprPlane[n16];
1030
                        colorBits <= sprColorDepth[n16];
1031
                end
1032
end
1033
 
1034
 
1035
// combine the text / graphics color output with sprite color output
1036
// blend color output
1037
wire [35:0] blendedColor32 = {
1038
        fnBlend(out[31:24],{out[23:16],4'h0},zrgb_i[35:24]),
1039
        fnBlend(out[31:24],{out[15:8],4'h0},zrgb_i[23:12]),
1040
        fnBlend(out[31:24],{out[7:0],4'h0},zrgb_i[11: 0])}
1041
        ;
1042
 
1043
wire [35:0] blendedColor16 = {
1044
        fnBlend(out[7:0],zrgb_i[35:24],12'h0),
1045
        fnBlend(out[7:0],zrgb_i[23:12],12'h0),
1046
        fnBlend(out[7:0],zrgb_i[11: 0],12'h0)}
1047
        ;
1048
 
1049
always_ff @(posedge vclk)
1050
if (blank_i)
1051
        zrgb_o <= 0;
1052
else begin
1053
        if (outact) begin
1054
                if (zrgb_i[39:36] > outplane) begin                     // rgb input is in front of sprite
1055
                        zrgb_o <= zrgb_i;
1056
                end
1057
                else
1058
                if (!out[31]) begin                     // a sprite is displayed without alpha blending
1059
                        case(colorBits)
1060
                        2'd0:   zrgb_o <= {outplane,out[7:5],9'b0,out[4:2],9'b0,out[1:0],10'b0};
1061
                        2'd1:   zrgb_o <= {outplane,out[7:5],9'b0,out[4:2],9'b0,out[1:0],10'b0};
1062
                        2'd2:   zrgb_o <= {outplane,out[14:10],7'b0,out[9:5],7'b0,out[4:0],7'b0};
1063
                        2'd3:   zrgb_o <= zrgb_o <= {outplane,blendedColor32};  // combine colors {outplane,out[23:16],4'h0,out[15:8],4'h0,out[7:0],4'h0};
1064
                        endcase
1065
                end
1066
                else
1067
                        case(colorBits)
1068
                        2'd2:   zrgb_o <= {outplane,blendedColor16};    // towards black/white
1069
                        2'd3:   zrgb_o <= {outplane,blendedColor32};    // combine colors
1070
                        default:        zrgb_o <= {outplane,out[7:5],9'b0,out[4:2],9'b0,out[1:0],10'b0};        // no blending
1071
                        endcase
1072
        end
1073
        else
1074
                zrgb_o <= zrgb_i;
1075
end
1076
 
1077
 
1078
//--------------------------------------------------------------------
1079
// Collision logic
1080
//--------------------------------------------------------------------
1081
 
1082
// Detect when a sprite-sprite collision has occurred. The criteria
1083
// for this is that a pixel from the sprite is being displayed, while
1084
// there is a pixel from another sprite that could be displayed at the
1085
// same time.
1086
 
1087
//--------------------------------------------------------------------
1088
// ToDo: make collision also depend on plane
1089
//--------------------------------------------------------------------
1090
 
1091 9 robfinch
cntpop32 ucntp1 (
1092
        .i(sproact),
1093
        .o(actcnt)
1094
);
1095
 
1096 7 robfinch
// Detect when a sprite-background collision has occurred
1097
integer n31;
1098
always_comb
1099
for (n31 = 0; n31 < pnSpr; n31 = n31 + 1)
1100
        bkCollision[n31] <=
1101
                sproact[n31] && zrgb_i[39:36]==sprPlane[n31];
1102
 
1103
// Load the sprite collision register. This register continually
1104
// accumulates collision bits until reset by reading the register.
1105
// Set the collision IRQ on the first collision and don't set it
1106
// again until after the collision register has been read.
1107
always @(posedge vclk)
1108
if (rst_i) begin
1109
        sprSprIRQPending1 <= 0;
1110
        sprSprCollision1 <= 0;
1111
        sprSprIRQ1 <= 0;
1112
end
1113 9 robfinch
else if (actcnt > 6'd1) begin
1114 7 robfinch
        // isFirstCollision
1115
        if ((sprSprCollision1==0)||(cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110010)) begin
1116
                sprSprIRQPending1 <= 1;
1117
                sprSprIRQ1 <= sprSprIe;
1118
                sprSprCollision1 <= sproact;
1119
        end
1120
        else
1121
                sprSprCollision1 <= sprSprCollision1|sproact;
1122
end
1123
else if (cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110010) begin
1124
        sprSprCollision1 <= 0;
1125
        sprSprIRQPending1 <= 0;
1126
        sprSprIRQ1 <= 0;
1127
end
1128
 
1129
 
1130
// Load the sprite background collision register. This register
1131
// continually accumulates collision bits until reset by reading
1132
// the register.
1133
// Set the collision IRQ on the first collision and don't set it
1134
// again until after the collision register has been read.
1135
// Note the background collision indicator is externally supplied,
1136
// it will come from the color processing logic.
1137
always @(posedge vclk)
1138
if (rst_i) begin
1139
        sprBkIRQPending1 <= 0;
1140
        sprBkCollision1 <= 0;
1141
        sprBkIRQ1 <= 0;
1142
end
1143
else if (|bkCollision) begin
1144
        // Is the register being cleared at the same time
1145
        // a collision occurss ?
1146
        // isFirstCollision
1147
        if ((sprBkCollision1==0) || (cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110011)) begin
1148
                sprBkIRQ1 <= sprBkIe;
1149
                sprBkCollision1 <= bkCollision;
1150
                sprBkIRQPending1 <= 1;
1151
        end
1152
        else
1153
                sprBkCollision1 <= sprBkCollision1|bkCollision;
1154
end
1155
else if (cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110011) begin
1156
        sprBkCollision1 <= 0;
1157
        sprBkIRQPending1 <= 0;
1158
        sprBkIRQ1 <= 0;
1159
end
1160
 
1161
endmodule
1162
 
1163
/*
1164
module SpriteRam32 (
1165
        clka, adra, dia, doa, cea, wea,
1166
        clkb, adrb, dib, dob, ceb, web
1167
);
1168
input clka;
1169
input [9:0] adra;
1170
input [31:0] dia;
1171
output [31:0] doa;
1172
input cea;
1173
input wea;
1174
input clkb;
1175
input [9:0] adrb;
1176
input [31:0] dib;
1177
output [31:0] dob;
1178
input ceb;
1179
input web;
1180
 
1181
reg [31:0] mem [0:1023];
1182
reg [9:0] radra;
1183
reg [9:0] radrb;
1184
 
1185
always @(posedge clka)  if (cea) radra <= adra;
1186
always @(posedge clkb)  if (ceb) radrb <= adrb;
1187
assign doa = mem [radra];
1188
assign dob = mem [radrb];
1189
always @(posedge clka)
1190
        if (cea & wea) mem[adra] <= dia;
1191
always @(posedge clkb)
1192
        if (ceb & web) mem[adrb] <= dib;
1193
 
1194
endmodule
1195
 
1196
*/

powered by: WebSVN 2.1.0

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