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 7

Go to most recent revision | 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
//=============================================================================
141
 
142
import wishbone_pkg::*;
143
 
144
module rfSpriteController(
145
// Bus Slave interface
146
//------------------------------
147
// Slave signals
148
input rst_i,                    // reset
149
input s_clk_i,          // clock
150
input s_cs_i,
151
input   wb_write_request32_t wbs_req,
152
output wb_read_response32_t wbs_resp,
153
//------------------------------
154
// Bus Master Signals
155
input m_clk_i,                          // clock
156
output wb_write_request128_t wbm_req,
157
input wb_read_response128_t wbm_resp,
158
output [4:0] m_spriteno_o,
159
//--------------------------
160
input dot_clk_i,                // video dot clock
161
input hsync_i,                  // horizontal sync pulse
162
input vsync_i,                  // vertical sync pulse
163
input blank_i,                  // blanking signal
164
input [39:0] zrgb_i,                    // input pixel stream
165
output [39:0] zrgb_o,   // output pixel stream 12-12-12-4
166
output irq,                                     // interrupt request
167
input test,
168
input xonoff_i
169
);
170
 
171
reg m_soc_o;
172
wire vclk = dot_clk_i;
173
wire hSync = hsync_i;
174
wire vSync = vsync_i;
175
reg [39:0] zrgb_o;
176
 
177
//--------------------------------------------------------------------
178
// Core Parameters
179
//--------------------------------------------------------------------
180
parameter pnSpr = 32;           // number of sprites
181
parameter phBits = 12;          // number of bits in horizontal timing counter
182
parameter pvBits = 12;          // number of bits in vertical timing counter
183
localparam pnSprm = pnSpr-1;
184
 
185
 
186
//--------------------------------------------------------------------
187
// Variable Declarations
188
//--------------------------------------------------------------------
189
 
190
reg ce;                                                                         // controller enable
191
wb_write_request32_t wb_reqs;   // synchronized request
192
 
193
wire [4:0] sprN = wb_reqs.adr[8:4];
194
 
195
reg [phBits-1:0] hctr;          // horizontal reference counter (counts dots since hSync)
196
reg [pvBits-1:0] vctr;          // vertical reference counter (counts scanlines since vSync)
197
reg sprSprIRQ;
198
reg sprBkIRQ;
199
 
200
reg [31:0] out;                 // sprite output
201
reg outact;                             // sprite output is active
202
reg [3:0] outplane;
203
reg [pnSprm:0] bkCollision;             // sprite-background collision
204
reg [29:0] bgTc;                        // background transparent color
205
reg [29:0] bkColor;             // background color
206
 
207
 
208
reg [pnSprm:0] sprWe;   // block ram write enable for image cache update
209
reg [pnSprm:0] sprRe;   // block ram read enable for image cache update
210
 
211
// Global control registers
212
reg [31:0] sprEn;       // enable sprite
213
reg [pnSprm:0] sprCollision;        // sprite-sprite collision
214
reg sprSprIe;                   // sprite-sprite interrupt enable
215
reg sprBkIe;            // sprite-background interrupt enable
216
reg sprSprIRQPending;   // sprite-sprite collision interrupt pending
217
reg sprBkIRQPending;    // sprite-background collision interrupt pending
218
reg sprSprIRQPending1;  // sprite-sprite collision interrupt pending
219
reg sprBkIRQPending1;   // sprite-background collision interrupt pending
220
reg sprSprIRQ1;                 // vclk domain regs
221
reg sprBkIRQ1;
222
 
223
// Sprite control registers
224
reg [31:0] sprSprCollision;
225
reg [pnSprm:0] sprSprCollision1;
226
reg [31:0] sprBkCollision;
227
reg [pnSprm:0] sprBkCollision1;
228
reg [23:0] sprTc [pnSprm:0];            // sprite transparent color code
229
// How big the pixels are:
230
// 1 to 16 video clocks
231
reg [3:0] hSprRes [pnSprm:0];           // sprite horizontal resolution
232
reg [3:0] vSprRes [pnSprm:0];           // sprite vertical resolution
233
reg [7:0] sprWidth [pnSprm:0];          // number of pixels in X direction
234
reg [7:0] sprHeight [pnSprm:0];         // number of vertical pixels
235
reg [3:0] sprPlane [pnSprm:0];          // output plane sprite is in
236
reg [1:0] sprColorDepth [pnSprm:0];
237
reg [1:0] colorBits;
238
// Sprite DMA control
239
reg [8:0] sprBurstStart [pnSprm:0];
240
reg [8:0] sprBurstEnd   [pnSprm:0];
241
reg [31:0] vSyncT;                                                              // DMA on vSync
242
 
243
// display and timing signals
244
reg [31:0] hSprReset;   // horizontal reset
245
reg [31:0] vSprReset;   // vertical reset
246
reg [31:0] hSprDe;              // sprite horizontal display enable
247
reg [31:0] vSprDe;              // sprite vertical display enable
248
reg [31:0] sprDe;                       // display enable
249
reg [phBits-1:0] hSprPos [pnSprm:0];    // sprite horizontal position
250
reg [pvBits-1:0] vSprPos [pnSprm:0];    // sprite vertical position
251
reg [7:0] hSprCnt [pnSprm:0];   // sprite horizontal display counter
252
reg [7:0] vSprCnt [pnSprm:0];   // vertical display counter
253
reg [11:0] sprImageOffs [pnSprm:0];     // offset within sprite memory
254
reg [12:0] sprAddr [pnSprm:0];  // index into sprite memory (pixel number)
255
reg [9:0] sprAddr1 [pnSprm:0];  // index into sprite memory
256
reg [2:0] sprAddr2 [pnSprm:0];  // index into sprite memory
257
reg [2:0] sprAddr3 [pnSprm:0];  // index into sprite memory
258
reg [2:0] sprAddr4 [pnSprm:0];  // index into sprite memory
259
reg [2:0] sprAddr5 [pnSprm:0];  // index into sprite memory
260
reg [11:0] sprAddrB [pnSprm:0]; // backup address cache for rescan
261
wire [31:0] sprOut4 [pnSprm:0]; // sprite image data output
262
reg [31:0] sprOut [pnSprm:0];   // sprite image data output
263
reg [31:0] sprOut5 [pnSprm:0];  // sprite image data output
264
 
265
// Animation
266
reg [11:0] sprFrameSize [pnSprm:0];
267
reg [7:0] sprFrames [pnSprm:0];
268
reg [7:0] sprCurFrame [pnSprm:0];
269
reg [9:0] sprRate [pnSprm:0];
270
reg [9:0] sprCurRateCount [pnSprm:0];
271
reg [pnSprm:0] sprEnableAnimation;
272
reg [pnSprm:0] sprAutoRepeat;
273
 
274
// DMA access
275
reg [31:12] sprSysAddr [pnSprm:0];      // system memory address of sprite image (low bits)
276
reg [4:0] dmaOwner;                     // which sprite has the DMA channel
277
reg [31:0] sprDt;               // DMA trigger register
278
reg dmaActive;                          // this flag indicates that a block DMA transfer is active
279
 
280
genvar g;
281
 
282
//--------------------------------------------------------------------
283
// DMA control / bus interfacing
284
//--------------------------------------------------------------------
285
reg cs_regs;
286
always_ff @(posedge s_clk_i)
287
        cs_regs <= wbs_req.cyc & wbs_req.stb & s_cs_i;
288
always_ff @(posedge s_clk_i)
289
        wb_reqs <= wbs_req;
290
 
291
wire s_ack_o;
292
ack_gen #(
293
        .READ_STAGES(3),
294
        .WRITE_STAGES(1),
295
        .REGISTER_OUTPUT(1)
296
)
297
uag1 (
298
        .clk_i(s_clk_i),
299
        .ce_i(1'b1),
300
        .i(cs_regs),
301
        .we_i(cs_regs & wb_reqs.we),
302
        .o(s_ack_o),
303
        .rid_i(0),
304
        .wid_i(0),
305
        .rid_o(),
306
        .wid_o()
307
);
308
always_comb
309
begin
310
        wbs_resp.ack = s_ack_o & wbs_req.cyc & wbs_req.stb;
311
        wbs_resp.next = s_ack_o & wbs_req.cyc & wbs_req.stb;
312
end
313
 
314
assign irq = sprSprIRQ|sprBkIRQ;
315
 
316
//--------------------------------------------------------------------
317
// DMA control / bus interfacing
318
//--------------------------------------------------------------------
319
 
320
reg [5:0] dmaStart;
321
reg [8:0] cob;  // count of burst cycles
322
 
323
assign wbm_req.bte = LINEAR;
324
assign wbm_req.cti = CLASSIC;
325
assign wbm_req.stb = wbm_req.cyc;
326
assign wbm_req.sel = 16'hFFFF;
327
assign wbm_req.cid = 4'd5;
328
assign m_spriteno_o = dmaOwner;
329
 
330
reg [2:0] mstate;
331
parameter IDLE = 3'd0;
332
parameter ACTIVE = 3'd1;
333
parameter ACK = 3'd2;
334
parameter NACK = 3'd3;
335
 
336
wire pe_m_ack_i;
337
edge_det ued2 (.rst(rst_i), .clk(m_clk_i), .ce(1'b1), .i(wbm_resp.ack), .pe(pe_m_ack_i), .ne(), .ee());
338
 
339
always_ff @(posedge m_clk_i)
340
if (rst_i)
341
        mstate <= IDLE;
342
else begin
343
        case(mstate)
344
        IDLE:
345
                if (|sprDt & ce)
346
                        mstate <= ACTIVE;
347
        ACTIVE:
348
                mstate <= ACK;
349
        ACK:
350
                if (wbm_resp.ack | wbm_resp.err)
351
                        mstate <= NACK;
352
        NACK:
353
                if (~(wbm_resp.ack|wbm_resp.err))
354
                        mstate <= cob==sprBurstEnd[dmaOwner] ? IDLE : ACTIVE;
355
        default:
356
                mstate <= IDLE;
357
        endcase
358
end
359
 
360
integer n30;
361
always_ff @(posedge m_clk_i)
362
begin
363
        case(mstate)
364
        IDLE:
365
                begin
366
                        dmaOwner <= 5'd0;
367
                        for (n30 = pnSprm; n30 >= 0; n30 = n30 - 1)
368
                                if (sprDt[n30])
369
                                        dmaOwner <= n30;
370
                end
371
        default:        ;
372
        endcase
373
end
374
 
375
always_ff @(posedge m_clk_i)
376
if (rst_i)
377
        dmaStart <= 6'b0;
378
else begin
379
        dmaStart <= {dmaStart[4:0],1'b0};
380
        case(mstate)
381
        IDLE:
382
                if (|sprDt & ce)
383
                        dmaStart <= 6'h3F;
384
        default:        ;
385
        endcase
386
end
387
 
388
integer n32;
389
always_ff @(posedge m_clk_i)
390
begin
391
        case(mstate)
392
        IDLE:
393
                for (n32 = pnSprm; n32 >= 0; n32 = n32 - 1)
394
                        if (sprDt[n32])
395
                                cob <= sprBurstStart[n32];
396
        ACTIVE:
397
                cob <= cob + 2'd2;
398
        default:        ;
399
        endcase
400
end
401
 
402
always_ff @(posedge m_clk_i)
403
if (rst_i)
404
        wb_m_nack();
405
else begin
406
        case(mstate)
407
        IDLE:
408
                wb_m_nack();
409
        ACTIVE:
410
                begin
411
                        wbm_req.cyc <= 1'b1;
412
                        wbm_req.adr <= {sprSysAddr[dmaOwner],cob[8:1],4'h0};
413
                end
414
        ACK:
415
                if (wbm_resp.ack|wbm_resp.err)
416
                        wb_m_nack();
417
        endcase
418
end
419
 
420
task wb_m_nack;
421
begin
422
        wbm_req.cyc <= 1'b0;
423
end
424
endtask
425
 
426
 
427
// generate a write enable strobe for the sprite image memory
428
integer n1;
429
reg [8:0] m_adr_or;
430
reg [127:0] m_dat_ir;
431
reg ack1;
432
 
433
always_ff @(posedge m_clk_i)
434
for (n1 = 0; n1 < pnSpr; n1 = n1 + 1)
435
        sprWe[n1] <= (dmaOwner==n1 && (pe_m_ack_i||ack1));
436
 
437
always_ff @(posedge m_clk_i)
438
        ack1 <= pe_m_ack_i;
439
always_ff @(posedge m_clk_i)
440
if (pe_m_ack_i|ack1)
441
        m_adr_or <= {wbm_req.adr[11:4],ack1};
442
always_ff @(posedge m_clk_i)
443
if (pe_m_ack_i) begin
444
        if (test)
445
                m_dat_ir <= {8{1'b0,dmaOwner,10'b0}};
446
        else
447
                m_dat_ir <= {wbm_resp.dat[63:0],wbm_resp.dat[127:64]};
448
end
449
else if (ack1)
450
        m_dat_ir <= {64'd0,m_dat_ir[127:64]};
451
 
452
 
453
//--------------------------------------------------------------------
454
//--------------------------------------------------------------------
455
 
456
reg [31:0] reg_shadow [0:255];
457
reg [7:0] radr;
458
always_ff @(posedge s_clk_i)
459
begin
460
    if (cs_regs & wb_reqs.we & wb_reqs.sel[0])  reg_shadow[wb_reqs.adr[9:2]][7:0] <= wb_reqs.dat[7:0];
461
    if (cs_regs & wb_reqs.we & wb_reqs.sel[1])  reg_shadow[wb_reqs.adr[9:2]][15:8] <= wb_reqs.dat[15:8];
462
    if (cs_regs & wb_reqs.we & wb_reqs.sel[2])  reg_shadow[wb_reqs.adr[9:2]][23:16] <= wb_reqs.dat[23:16];
463
    if (cs_regs & wb_reqs.we & wb_reqs.sel[3])  reg_shadow[wb_reqs.adr[9:2]][31:24] <= wb_reqs.dat[31:24];
464
end
465
always @(posedge s_clk_i)
466
  radr <= wb_reqs.adr[9:2];
467
wire [31:0] reg_shadow_o = reg_shadow[radr];
468
 
469
// register/sprite memory output mux
470
always_ff @(posedge s_clk_i)
471
        if (cs_regs)
472
                case (wb_reqs.adr[9:2])         // synopsys full_case parallel_case
473
                8'b11110000:    wbs_resp.dat <= sprEn;
474
                8'b11110001:    wbs_resp.dat <= {sprBkIRQPending|sprSprIRQPending,5'b0,sprBkIRQPending,sprSprIRQPending,6'b0,sprBkIe,sprSprIe};
475
                8'b11110010:    wbs_resp.dat <= sprSprCollision;
476
                8'b11110011:    wbs_resp.dat <= sprBkCollision;
477
                8'b11110100:    wbs_resp.dat <= sprDt;
478
                default:        wbs_resp.dat <= reg_shadow_o;
479
                endcase
480
        else
481
                wbs_resp.dat <= 32'h0;
482
 
483
 
484
// vclk -> clk_i
485
always @(posedge s_clk_i)
486
begin
487
        sprSprIRQ <= sprSprIRQ1;
488
        sprBkIRQ <= sprBkIRQ1;
489
        sprSprIRQPending <= sprSprIRQPending1;
490
        sprBkIRQPending <= sprBkIRQPending1;
491
        sprSprCollision <= sprSprCollision1;
492
        sprBkCollision <= sprBkCollision1;
493
end
494
 
495
 
496
// register updates
497
// on the clk_i domain
498
reg vSync1;
499
integer n33;
500
always_ff @(posedge s_clk_i)
501
if (rst_i) begin
502
        vSyncT <= 32'hFFFF0000;//FFFFFFFF;
503
        sprEn <= 32'hFFFFFFFF;
504
        sprDt <= 0;
505
  for (n33 = 0; n33 < pnSpr; n33 = n33 + 1) begin
506
                sprSysAddr[n33] <= 20'b0000_0000_0011_0000_0000 + n33;  //0030_0000
507
        end
508
        sprSprIe <= 0;
509
        sprBkIe  <= 0;
510
 
511
  // Set reasonable starting positions on the screen
512
  // so that the sprites might be visible for testing
513
  for (n33 = 0; n33 < pnSpr; n33 = n33 + 1) begin
514
    hSprPos[n33] <= 200 + (n33 & 7) * 70;
515
    vSprPos[n33] <= 100 + (n33 >> 3) * 100;
516
    sprTc[n33] <= 24'h7FFF;             // White 16 bpp
517
                sprWidth[n33] <= 8'd16;         // 16x16 sprites
518
                sprHeight[n33] <= 8'd16;
519
                hSprRes[n33] <= 2;      // our standard display
520
                vSprRes[n33] <= 2;
521
                sprImageOffs[n33] <= 0;
522
                sprPlane[n33] <= 4'hF;//n[3:0];
523
                sprBurstStart[n33] <= 9'h000;
524
                sprBurstEnd[n33] <= 9'h1FE;
525
                sprColorDepth[n33] <= 2'b10;
526
                sprFrameSize[n33] <= 12'd256;
527
                sprFrames[n33] <= 8'd5;
528
                sprRate[n33] <= 12'd10;
529
                sprEnableAnimation[n33] <= 1'b1;
530
                sprAutoRepeat[n33] <= 1'b1;
531
        end
532
  hSprPos[0] <= 210;
533
  vSprPos[0] <= 72;
534
 
535
  bgTc <= 24'h08_08_08;
536
  bkColor <= 24'hFF_FF_60;
537
end
538
else begin
539
        ce <= xonoff_i;
540
        vSync1 <= vSync;
541
        if (vSync & ~vSync1)
542
                sprDt <= sprDt | vSyncT;
543
 
544
        // clear DMA trigger bit once DMA is recognized
545
        if (dmaStart[5])
546
                sprDt[dmaOwner] <= 1'b0;
547
 
548
        // Disable animation after frame count expired, if not auto-repeat.
549
  for (n33 = 0; n33 < pnSpr; n33 = n33 + 1)
550
                if (sprCurFrame[n33] >= sprFrames[n33] && !sprAutoRepeat[n33])
551
                        sprEnableAnimation[n33] <= 1'b0;
552
 
553
        if (cs_regs & wb_reqs.we) begin
554
 
555
                casez (wb_reqs.adr[9:2])
556
                8'b100?????:
557
                        begin
558
                                if (&wb_reqs.sel[1:0]) sprBurstStart[wb_reqs.adr[6:2]] <= {wb_reqs.dat[8:1],1'b0};
559
                                if (&wb_reqs.sel[3:2]) sprBurstEnd[wb_reqs.adr[6:2]] <= {wb_reqs.dat[24:17],1'b0};
560
                        end
561
                8'b101?????:
562
                        begin
563
                                if (wb_reqs.sel[0]) sprFrameSize[wb_reqs.adr[6:2]][11:4] <= wb_reqs.dat[7:0];
564
                                if (wb_reqs.sel[1]) sprFrames[wb_reqs.adr[6:2]] <= wb_reqs.dat[15:8];
565
                                if (wb_reqs.sel[2]) sprRate[wb_reqs.adr[6:2]][7:0] <= wb_reqs.dat[23:16];
566
                                if (wb_reqs.sel[3])
567
                                        begin
568
                                                sprRate[wb_reqs.adr[6:2]][9:8] <= wb_reqs.dat[25:24];
569
                                                sprFrameSize[wb_reqs.adr[6:2]][3:0] <= wb_reqs.dat[29:26];
570
                                                sprAutoRepeat[wb_reqs.adr[6:2]] <= wb_reqs.dat[30];
571
                                                sprEnableAnimation[wb_reqs.adr[6:2]] <= wb_reqs.dat[31];
572
                                        end
573
                        end
574
                8'b11110000:    // 3C0
575
                        begin
576
                                if (wb_reqs.sel[0]) sprEn[7:0] <= wb_reqs.dat[7:0];
577
                                if (wb_reqs.sel[1]) sprEn[15:8] <= wb_reqs.dat[15:8];
578
                                if (wb_reqs.sel[2]) sprEn[23:16] <= wb_reqs.dat[23:16];
579
                                if (wb_reqs.sel[3]) sprEn[31:24] <= wb_reqs.dat[31:24];
580
                        end
581
                8'b11110001:    // 3C4
582
                        if (wb_reqs.sel[0]) begin
583
                                sprSprIe <= wb_reqs.dat[0];
584
                                sprBkIe <= wb_reqs.dat[1];
585
                        end
586
                // update DMA trigger
587
                // s_wb_reqs.dat[7:0] indicates which triggers to set  (1=set,0=ignore)
588
                // s_wb_reqs.dat[7:0] indicates which triggers to clear (1=clear,0=ignore)
589
                8'b11110100:    // 3D0
590
                        begin
591
                                if (wb_reqs.sel[0])     sprDt[7:0] <= sprDt[7:0] | wb_reqs.dat[7:0];
592
                                if (wb_reqs.sel[1]) sprDt[15:8] <= sprDt[15:8] | wb_reqs.dat[15:8];
593
                                if (wb_reqs.sel[2]) sprDt[23:16] <= sprDt[23:16] | wb_reqs.dat[23:16];
594
                                if (wb_reqs.sel[3])     sprDt[31:24] <= sprDt[31:24] | wb_reqs.dat[31:24];
595
                        end
596
                8'b11110101:    // 3D4
597
                        begin
598
                                if (wb_reqs.sel[0])     sprDt[7:0] <= sprDt[7:0] & ~wb_reqs.dat[7:0];
599
                                if (wb_reqs.sel[1]) sprDt[15:8] <= sprDt[15:8] & ~wb_reqs.dat[15:8];
600
                                if (wb_reqs.sel[2]) sprDt[23:16] <= sprDt[23:16] & ~wb_reqs.dat[23:16];
601
                                if (wb_reqs.sel[3])     sprDt[31:24] <= sprDt[31:24] & ~wb_reqs.dat[31:24];
602
                        end
603
                8'b11110110:    // 3D8
604
                        begin
605
                                if (wb_reqs.sel[0])     vSyncT[7:0] <= wb_reqs.dat[7:0];
606
                                if (wb_reqs.sel[1]) vSyncT[15:8] <= wb_reqs.dat[15:8];
607
                                if (wb_reqs.sel[2]) vSyncT[23:16] <= wb_reqs.dat[23:16];
608
                                if (wb_reqs.sel[3])     vSyncT[31:24] <= wb_reqs.dat[31:24];
609
                        end
610
                8'b11111010:    // 3E8
611
                        begin
612
                                if (wb_reqs.sel[0])     bgTc[7:0] <= wb_reqs.dat[7:0];
613
                                if (wb_reqs.sel[1])     bgTc[15:8] <= wb_reqs.dat[15:8];
614
                                if (wb_reqs.sel[2])     bgTc[23:16] <= wb_reqs.dat[23:16];
615
                                if (wb_reqs.sel[3])     bgTc[29:24] <= wb_reqs.dat[29:24];
616
                        end
617
                8'b11111011:    // 3EC
618
                        begin
619
                                if (wb_reqs.sel[0]) bkColor[7:0] <= wb_reqs.dat[7:0];
620
                                if (wb_reqs.sel[1]) bkColor[15:8] <= wb_reqs.dat[15:8];
621
                                if (wb_reqs.sel[2]) bkColor[23:16] <= wb_reqs.dat[23:16];
622
                                if (wb_reqs.sel[3]) bkColor[29:24] <= wb_reqs.dat[29:24];
623
                        end
624
//              8'b11111100:    // 3F0
625
//                      if (wb_reqs.sel[0]) ce <= wb_reqs[0];
626
                8'b0?????00:
627
                         begin
628
                        if (wb_reqs.sel[0]) hSprPos[sprN][ 7:0] <= wb_reqs.dat[ 7: 0];
629
                        if (wb_reqs.sel[1]) hSprPos[sprN][11:8] <= wb_reqs.dat[11: 8];
630
                        if (wb_reqs.sel[2]) vSprPos[sprN][ 7:0] <= wb_reqs.dat[23:16];
631
                        if (wb_reqs.sel[3]) vSprPos[sprN][11:8] <= wb_reqs.dat[27:24];
632
                end
633
    8'b0?????01:
634
                        begin
635
                if (wb_reqs.sel[0]) begin
636
                                        sprWidth[sprN] <= wb_reqs.dat[7:0];
637
        end
638
                if (wb_reqs.sel[1]) begin
639
                                        sprHeight[sprN] <= wb_reqs.dat[15:8];
640
        end
641
                                if (wb_reqs.sel[2]) begin
642
                hSprRes[sprN] <= wb_reqs.dat[19:16];
643
                vSprRes[sprN] <= wb_reqs.dat[23:20];
644
                                end
645
                                if (wb_reqs.sel[3]) begin
646
                                        sprPlane[sprN] <= wb_reqs.dat[27:24];
647
                                        sprColorDepth[sprN] <= wb_reqs.dat[31:30];
648
                                end
649
                        end
650
                8'b0?????10:
651
                        begin   // DMA address set on clk_i domain
652
        if (wb_reqs.sel[0]) sprImageOffs[sprN][ 7:0] <= wb_reqs.dat[7:0];
653
        if (wb_reqs.sel[1]) sprImageOffs[sprN][11:8] <= wb_reqs.dat[11:8];
654
                                if (wb_reqs.sel[1]) sprSysAddr[sprN][15:12] <= wb_reqs.dat[15:12];
655
                                if (wb_reqs.sel[2]) sprSysAddr[sprN][23:16] <= wb_reqs.dat[23:16];
656
                                if (wb_reqs.sel[3]) sprSysAddr[sprN][31:24] <= wb_reqs.dat[31:24];
657
                        end
658
                8'b0?????11:
659
                        begin
660
                                if (wb_reqs.sel[0]) sprTc[sprN][ 7:0] <= wb_reqs.dat[ 7:0];
661
                                if (wb_reqs.sel[1]) sprTc[sprN][15:8] <= wb_reqs.dat[15:8];
662
                                if (wb_reqs.sel[2]) sprTc[sprN][23:16] <= wb_reqs.dat[23:16];
663
                        end
664
 
665
                default:        ;
666
                endcase
667
 
668
        end
669
end
670
 
671
//-------------------------------------------------------------
672
// Sprite Image Cache RAM
673
// This RAM is dual ported with an SoC side and a display
674
// controller side.
675
//-------------------------------------------------------------
676
 
677
integer n2;
678
always_ff @(posedge vclk)
679
for (n2 = 0; n2 < pnSpr; n2 = n2 + 1)
680
case(sprColorDepth[n2])
681
2'd1:   sprAddr1[n2] <= {sprAddr[n2][11:3],~sprAddr[n2][2]};
682
2'd2:   sprAddr1[n2] <= {sprAddr[n2][10:2],~sprAddr[n2][1]};
683
2'd3:   sprAddr1[n2] <= {sprAddr[n2][ 9:1],~sprAddr[n2][0]};
684
default:        ;
685
endcase
686
 
687
// The three LSBs of the image index need to be pipelined so they may be used
688
// to select the pixel. Output from the SRAM is always 32-bits wide so an
689
// additional mux is needed.
690
integer n4, n5, n27, n29;
691
always_ff @(posedge vclk)
692
for (n4 = 0; n4 < pnSpr; n4 = n4 + 1)
693
        sprAddr2[n4] <= ~sprAddr[n4][2:0];
694
always_ff @(posedge vclk)
695
for (n5 = 0; n5 < pnSpr; n5 = n5 + 1)
696
        sprAddr3[n5] <= sprAddr2[n5];
697
always_ff @(posedge vclk)
698
for (n27 = 0; n27 < pnSpr; n27 = n27 + 1)
699
        sprAddr4[n27] <= sprAddr3[n27];
700
always_ff @(posedge vclk)
701
for (n29 = 0; n29 < pnSpr; n29 = n29 + 1)
702
        sprAddr5[n29] <= sprAddr4[n29];
703
 
704
// The pixels are displayed from most signicant to least signicant bits of the
705
// word. Display order is opposite to memory storage. So, the least significant
706
// address bits are flipped to get the correct display.
707
integer n3;
708
always_ff @(posedge vclk)
709
for (n3 = 0; n3 < pnSpr; n3 = n3 + 1)
710
case(sprColorDepth[n3])
711
2'd1:
712
        case(sprAddr5[n3][1:0])
713
        2'd3:   sprOut5[n3] <= sprOut4[n3][31:24];
714
        2'd2:   sprOut5[n3] <= sprOut4[n3][23:16];
715
        2'd1:   sprOut5[n3] <= sprOut4[n3][15:8];
716
        2'd0:   sprOut5[n3] <= sprOut4[n3][7:0];
717
        endcase
718
2'd2:
719
        case(sprAddr5[n3][0])
720
        1'd0:   sprOut5[n3] <= {sprOut4[n3][15],16'h0000,sprOut4[n3][14:0]};
721
        1'd1:   sprOut5[n3] <= {sprOut4[n3][31],16'h0000,sprOut4[n3][30:16]};
722
        endcase
723
2'd3:
724
        sprOut5[n3] <= sprOut4[n3];
725
default:        ;
726
endcase
727
 
728
generate
729
for (g = 0; g < pnSpr; g = g + 1) begin : sprRam
730
        SpriteRam sprRam0
731
        (
732
                .clka(m_clk_i),
733
                .addra(m_adr_or),
734
                .dina(m_dat_ir[63:0]),
735
                .ena(sprWe[g]),
736
                .wea(sprWe[g]),
737
                // Core reg and output reg 3 clocks from read address
738
                .clkb(vclk),
739
                .addrb(sprAddr1[g]),
740
                .doutb(sprOut4[g]),
741
                .enb(1'b1)
742
        );
743
        end
744
endgenerate
745
 
746
//-------------------------------------------------------------
747
// Timing counters and addressing
748
// Sprites are like miniature bitmapped displays, they need
749
// all the same timing controls.
750
//-------------------------------------------------------------
751
 
752
// Create a timing reference using horizontal and vertical
753
// sync
754
wire hSyncEdge, vSyncEdge;
755
edge_det ed0(.rst(rst_i), .clk(vclk), .ce(1'b1), .i(hSync), .pe(hSyncEdge), .ne(), .ee() );
756
edge_det ed1(.rst(rst_i), .clk(vclk), .ce(1'b1), .i(vSync), .pe(vSyncEdge), .ne(), .ee() );
757
 
758
always_ff @(posedge vclk)
759
if (hSyncEdge) hctr <= {phBits{1'b0}};
760
else hctr <= hctr + 2'd1;
761
 
762
always_ff @(posedge vclk)
763
if (vSyncEdge) vctr <= {pvBits{1'b0}};
764
else if (hSyncEdge) vctr <= vctr + 2'd1;
765
 
766
// track sprite horizontal reset
767
integer n19;
768
always_ff @(posedge vclk)
769
for (n19 = 0; n19 < pnSpr; n19 = n19 + 1)
770
        hSprReset[n19] <= hctr==hSprPos[n19];
771
 
772
// track sprite vertical reset
773
integer n20;
774
always_ff @(posedge vclk)
775
for (n20 = 0; n20 < pnSpr; n20 = n20 + 1)
776
        vSprReset[n20] <= vctr==vSprPos[n20];
777
 
778
integer n21;
779
always_comb
780
for (n21 = 0; n21 < pnSpr; n21 = n21 + 1)
781
        sprDe[n21] <= hSprDe[n21] & vSprDe[n21];
782
 
783
 
784
// take care of sprite size scaling
785
// video clock division
786
reg [31:0] hSprNextPixel;
787
reg [31:0] vSprNextPixel;
788
reg [3:0] hSprPt [31:0];   // horizontal pixel toggle
789
reg [3:0] vSprPt [31:0];   // vertical pixel toggle
790
integer n17;
791
always_comb
792
for (n17 = 0; n17 < pnSpr; n17 = n17 + 1)
793
    hSprNextPixel[n17] = hSprPt[n17]==hSprRes[n17];
794
integer n18;
795
always_comb
796
for (n18 = 0; n18 < pnSpr; n18 = n18 + 1)
797
    vSprNextPixel[n18] = vSprPt[n18]==vSprRes[n18];
798
 
799
// horizontal pixel toggle counter
800
integer n6;
801
always_ff @(posedge vclk)
802
for (n6 = 0; n6 < pnSpr; n6 = n6 + 1)
803
        if (hSprReset[n6])
804
                hSprPt[n6] <= 4'd0;
805
  else if (hSprNextPixel[n6])
806
    hSprPt[n6] <= 4'd0;
807
  else
808
    hSprPt[n6] <= hSprPt[n6] + 2'd1;
809
 
810
// vertical pixel toggle counter
811
integer n7;
812
always_ff @(posedge vclk)
813
for (n7 = 0; n7 < pnSpr; n7 = n7 + 1)
814
  if (hSprReset[n7]) begin
815
        if (vSprReset[n7])
816
                vSprPt[n7] <= 4'd0;
817
    else if (vSprNextPixel[n7])
818
      vSprPt[n7] <= 4'd0;
819
    else
820
      vSprPt[n7] <= vSprPt[n7] + 2'd1;
821
  end
822
 
823
// Animation rate count and frame increment.
824
integer n28;
825
always_ff @(posedge vclk)
826
        if (vSyncEdge) begin
827
                for (n28 = 0; n28 < pnSpr; n28 = n28 + 1) begin
828
                        if (sprEnableAnimation[n28]) begin
829
                                sprCurRateCount[n28] <= sprCurRateCount[n28] + 2'd1;
830
                                if (sprCurRateCount[n28] >= sprRate[n28]) begin
831
                                        sprCurRateCount[n28] <= 'd0;
832
                                        sprCurFrame[n28] <= sprCurFrame[n28] + 2'd1;
833
                                        if (sprCurFrame[n28] >= sprFrames[n28])
834
                                                sprCurFrame[n28] <= 'd0;
835
                                end
836
                        end
837
                        else
838
                                sprCurFrame[n28] <= 'd0;
839
                end
840
        end
841
 
842
// clock sprite image address counters
843
integer n8;
844
always_ff @(posedge vclk)
845
for (n8 = 0; n8 < pnSpr; n8 = n8 + 1) begin
846
    // hReset and vReset - top left of sprite,
847
    // reset address to image offset
848
        if (hSprReset[n8] & vSprReset[n8]) begin
849
                sprAddr[n8]  <= sprImageOffs[n8] + sprCurFrame[n8] * sprFrameSize[n8];
850
                sprAddrB[n8] <= sprImageOffs[n8] + sprCurFrame[n8] * sprFrameSize[n8];
851
        end
852
        // hReset:
853
        //  If the next vertical pixel
854
        //      set backup address to current address
855
        //  else
856
        //      set current address to backup address
857
        //      in order to rescan the line
858
        else if (hSprReset[n8]) begin
859
                if (vSprNextPixel[n8])
860
                        sprAddrB[n8] <= sprAddr[n8];
861
                else
862
                        sprAddr[n8]  <= sprAddrB[n8];
863
        end
864
        // Not hReset or vReset - somewhere on the sprite scan line
865
        // just advance the address when the next pixel should be
866
        // fetched
867
        else if (hSprDe[n8] & hSprNextPixel[n8])
868
                sprAddr[n8] <= sprAddr[n8] + 2'd1;
869
end
870
 
871
 
872
// clock sprite column (X) counter
873
integer n9;
874
always_ff @(posedge vclk)
875
for (n9 = 0; n9 < pnSpr; n9 = n9 + 1)
876
        if (hSprReset[n9])
877
                hSprCnt[n9] <= 8'd1;
878
        else if (hSprNextPixel[n9])
879
                hSprCnt[n9] <= hSprCnt[n9] + 2'd1;
880
 
881
 
882
// clock sprite horizontal display enable
883
integer n10;
884
always_ff @(posedge vclk)
885
for (n10 = 0; n10 < pnSpr; n10 = n10 + 1) begin
886
        if (hSprReset[n10])
887
                hSprDe[n10] <= 1'b1;
888
        else if (hSprNextPixel[n10]) begin
889
                if (hSprCnt[n10] == sprWidth[n10])
890
                        hSprDe[n10] <= 1'b0;
891
        end
892
end
893
 
894
 
895
// clock the sprite row (Y) counter
896
integer n11;
897
always_ff @(posedge vclk)
898
for (n11 = 0; n11 < pnSpr; n11 = n11 + 1)
899
        if (hSprReset[n11]) begin
900
                if (vSprReset[n11])
901
                        vSprCnt[n11] <= 8'd1;
902
                else if (vSprNextPixel[n11])
903
                        vSprCnt[n11] <= vSprCnt[n11] + 2'd1;
904
        end
905
 
906
 
907
// clock sprite vertical display enable
908
integer n12;
909
always_ff @(posedge vclk)
910
for (n12 = 0; n12 < pnSpr; n12 = n12 + 1) begin
911
        if (hSprReset[n12]) begin
912
                if (vSprReset[n12])
913
                        vSprDe[n12] <= 1'b1;
914
                else if (vSprNextPixel[n12]) begin
915
                        if (vSprCnt[n12] == sprHeight[n12])
916
                                vSprDe[n12] <= 1'b0;
917
                end
918
        end
919
end
920
 
921
 
922
//-------------------------------------------------------------
923
// Output stage
924
//-------------------------------------------------------------
925
 
926
// function used for color blending
927
// given an alpha and a color component, determine the resulting color
928
// this blends towards black or white
929
// alpha is eight bits ranging between 0 and 1.999...
930
// 1 bit whole, 7 bits fraction
931
function [11:0] fnBlend;
932
input [7:0] alpha;
933
input [11:0] color1bits;
934
input [11:0] color2bits;
935
 
936
begin
937
        fnBlend = (({8'b0,color1bits} * alpha) >> 7) + (({8'h00,color2bits} * (9'h100 - alpha)) >> 7);
938
end
939
endfunction
940
 
941
 
942
// pipeline delays for display enable
943
reg [31:0] sprDe1, sprDe2, sprDe3, sprDe4, sprDe5, sprDe6;
944
reg [31:0] sproact;
945
integer n13;
946
always_ff @(posedge vclk)
947
for (n13 = 0; n13 < pnSpr; n13 = n13 + 1)
948
        sprDe1[n13] <= sprDe[n13];
949
integer n22;
950
always_ff @(posedge vclk)
951
for (n22 = 0; n22 < pnSpr; n22 = n22 + 1)
952
        sprDe2[n22] <= sprDe1[n22];
953
integer n23;
954
always_ff @(posedge vclk)
955
for (n23 = 0; n23 < pnSpr; n23 = n23 + 1)
956
        sprDe3[n23] <= sprDe2[n23];
957
integer n24;
958
always_ff @(posedge vclk)
959
for (n24 = 0; n24 < pnSpr; n24 = n24 + 1)
960
        sprDe4[n24] <= sprDe3[n24];
961
integer n25;
962
always_ff @(posedge vclk)
963
for (n25 = 0; n25 < pnSpr; n25 = n25 + 1)
964
        sprDe5[n25] <= sprDe4[n25];
965
integer n26;
966
always_ff @(posedge vclk)
967
for (n26 = 0; n26 < pnSpr; n26 = n26 + 1)
968
        sprDe6[n26] <= sprDe5[n26];
969
 
970
 
971
// Detect which sprite outputs are active
972
// The sprite output is active if the current display pixel
973
// address is within the sprite's area, the sprite is enabled,
974
// and it's not a transparent pixel that's being displayed.
975
integer n14;
976
always_ff @(posedge vclk)
977
for (n14 = 0; n14 < pnSpr; n14 = n14 + 1)
978
        sproact[n14] <= sprEn[n14] && sprDe5[n14] && sprTc[n14]!=sprOut5[n14];
979
integer n15;
980
always_ff @(posedge vclk)
981
for (n15 = 0; n15 < pnSpr; n15 = n15 + 1)
982
        sprOut[n15] <= sprOut5[n15];
983
 
984
// register sprite activity flag
985
// The image combiner uses this flag to know what to do with
986
// the sprite output.
987
always_ff @(posedge vclk)
988
        outact <= |sproact & ce;
989
 
990
// Display data comes from the active sprite with the
991
// highest display priority.
992
// Make sure that alpha blending is turned off when
993
// no sprite is active.
994
integer n16;
995
always_ff @(posedge vclk)
996
begin
997
        out <= 32'h0080;        // alpha blend max (and off)
998
        outplane <= 4'h0;
999
        colorBits <= 2'b00;
1000
        for (n16 = pnSprm; n16 >= 0; n16 = n16 - 1)
1001
                if (sproact[n16]) begin
1002
                        out <= sprOut[n16];
1003
                        outplane <= sprPlane[n16];
1004
                        colorBits <= sprColorDepth[n16];
1005
                end
1006
end
1007
 
1008
 
1009
// combine the text / graphics color output with sprite color output
1010
// blend color output
1011
wire [35:0] blendedColor32 = {
1012
        fnBlend(out[31:24],{out[23:16],4'h0},zrgb_i[35:24]),
1013
        fnBlend(out[31:24],{out[15:8],4'h0},zrgb_i[23:12]),
1014
        fnBlend(out[31:24],{out[7:0],4'h0},zrgb_i[11: 0])}
1015
        ;
1016
 
1017
wire [35:0] blendedColor16 = {
1018
        fnBlend(out[7:0],zrgb_i[35:24],12'h0),
1019
        fnBlend(out[7:0],zrgb_i[23:12],12'h0),
1020
        fnBlend(out[7:0],zrgb_i[11: 0],12'h0)}
1021
        ;
1022
 
1023
always_ff @(posedge vclk)
1024
if (blank_i)
1025
        zrgb_o <= 0;
1026
else begin
1027
        if (outact) begin
1028
                if (zrgb_i[39:36] > outplane) begin                     // rgb input is in front of sprite
1029
                        zrgb_o <= zrgb_i;
1030
                end
1031
                else
1032
                if (!out[31]) begin                     // a sprite is displayed without alpha blending
1033
                        case(colorBits)
1034
                        2'd0:   zrgb_o <= {outplane,out[7:5],9'b0,out[4:2],9'b0,out[1:0],10'b0};
1035
                        2'd1:   zrgb_o <= {outplane,out[7:5],9'b0,out[4:2],9'b0,out[1:0],10'b0};
1036
                        2'd2:   zrgb_o <= {outplane,out[14:10],7'b0,out[9:5],7'b0,out[4:0],7'b0};
1037
                        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};
1038
                        endcase
1039
                end
1040
                else
1041
                        case(colorBits)
1042
                        2'd2:   zrgb_o <= {outplane,blendedColor16};    // towards black/white
1043
                        2'd3:   zrgb_o <= {outplane,blendedColor32};    // combine colors
1044
                        default:        zrgb_o <= {outplane,out[7:5],9'b0,out[4:2],9'b0,out[1:0],10'b0};        // no blending
1045
                        endcase
1046
        end
1047
        else
1048
                zrgb_o <= zrgb_i;
1049
end
1050
 
1051
 
1052
//--------------------------------------------------------------------
1053
// Collision logic
1054
//--------------------------------------------------------------------
1055
 
1056
// Detect when a sprite-sprite collision has occurred. The criteria
1057
// for this is that a pixel from the sprite is being displayed, while
1058
// there is a pixel from another sprite that could be displayed at the
1059
// same time.
1060
 
1061
//--------------------------------------------------------------------
1062
// Note this case has to be modified for the number of sprites
1063
// ToDo: make collision also depend on plane
1064
//--------------------------------------------------------------------
1065
generate
1066
begin : gSprsColliding
1067
always @(pnSpr or sproact)
1068
if (pnSpr==1)
1069
        sprCollision = 0;
1070
else if (pnSpr==2)
1071
        case (sproact)
1072
        2'b00,
1073
        2'b01,
1074
        2'b10:  sprCollision = 0;
1075
        2'b11:  sprCollision = 1;
1076
        endcase
1077
else if (pnSpr==4)
1078
        case (sproact)
1079
        4'b0000,
1080
        4'b0001,
1081
        4'b0010,
1082
        4'b0100,
1083
        4'b1000:        sprCollision = 0;
1084
        default:        sprCollision = 1;
1085
        endcase
1086
else if (pnSpr==6)
1087
        case (sproact)
1088
        6'b000000,
1089
        6'b000001,
1090
        6'b000010,
1091
        6'b000100,
1092
        6'b001000,
1093
        6'b010000,
1094
        8'b100000:      sprCollision = 0;
1095
        default:        sprCollision = 1;
1096
        endcase
1097
else if (pnSpr==8)
1098
        case (sproact)
1099
        8'b00000000,
1100
        8'b00000001,
1101
        8'b00000010,
1102
        8'b00000100,
1103
        8'b00001000,
1104
        8'b00010000,
1105
        8'b00100000,
1106
        8'b01000000,
1107
        8'b10000000:    sprCollision = 0;
1108
        default:                sprCollision = 1;
1109
        endcase
1110
else if (pnSpr==10)
1111
        case (sproact)
1112
        10'b0000000000,
1113
        10'b0000000001,
1114
        10'b0000000010,
1115
        10'b0000000100,
1116
        10'b0000001000,
1117
        10'b0000010000,
1118
        10'b0000100000,
1119
        10'b0001000000,
1120
        10'b0010000000,
1121
        10'b0100000000,
1122
        10'b1000000000: sprCollision = 0;
1123
        default:                sprCollision = 1;
1124
        endcase
1125
else if (pnSpr==14)
1126
        case (sproact)
1127
        14'b00000000000000,
1128
        14'b00000000000001,
1129
        14'b00000000000010,
1130
        14'b00000000000100,
1131
        14'b00000000001000,
1132
        14'b00000000010000,
1133
        14'b00000000100000,
1134
        14'b00000001000000,
1135
        14'b00000010000000,
1136
        14'b00000100000000,
1137
        14'b00001000000000,
1138
        14'b00010000000000,
1139
        14'b00100000000000,
1140
        14'b01000000000000,
1141
        14'b10000000000000:     sprCollision = 0;
1142
        default:                        sprCollision = 1;
1143
        endcase
1144
else if (pnSpr==16)
1145
        case (sproact)
1146
        16'h0000,
1147
        16'h0001,
1148
        16'h0002,
1149
        16'h0004,
1150
        16'h0008,
1151
        16'h0010,
1152
        16'h0020,
1153
        16'h0040,
1154
        16'h0080,
1155
        16'h0100,
1156
        16'h0200,
1157
        16'h0400,
1158
        16'h0800,
1159
        16'h1000,
1160
        16'h2000,
1161
        16'h4000,
1162
        16'h8000:       sprCollision = 0;
1163
        default:        sprCollision = 1;
1164
        endcase
1165
else if (pnSpr==32)
1166
        case (sproact)
1167
        32'h00000000,
1168
        32'h00000001,
1169
        32'h00000002,
1170
        32'h00000004,
1171
        32'h00000008,
1172
        32'h00000010,
1173
        32'h00000020,
1174
        32'h00000040,
1175
        32'h00000080,
1176
        32'h00000100,
1177
        32'h00000200,
1178
        32'h00000400,
1179
        32'h00000800,
1180
        32'h00001000,
1181
        32'h00002000,
1182
        32'h00004000,
1183
        32'h00008000,
1184
        32'h00010000,
1185
        32'h00020000,
1186
        32'h00040000,
1187
        32'h00080000,
1188
        32'h00100000,
1189
        32'h00200000,
1190
        32'h00400000,
1191
        32'h00800000,
1192
        32'h01000000,
1193
        32'h02000000,
1194
        32'h04000000,
1195
        32'h08000000,
1196
        32'h10000000,
1197
        32'h20000000,
1198
        32'h40000000,
1199
        32'h80000000:           sprCollision = 0;
1200
        default:                        sprCollision = 1;
1201
        endcase
1202
end
1203
endgenerate
1204
 
1205
// Detect when a sprite-background collision has occurred
1206
integer n31;
1207
always_comb
1208
for (n31 = 0; n31 < pnSpr; n31 = n31 + 1)
1209
        bkCollision[n31] <=
1210
                sproact[n31] && zrgb_i[39:36]==sprPlane[n31];
1211
 
1212
// Load the sprite collision register. This register continually
1213
// accumulates collision bits until reset by reading the register.
1214
// Set the collision IRQ on the first collision and don't set it
1215
// again until after the collision register has been read.
1216
always @(posedge vclk)
1217
if (rst_i) begin
1218
        sprSprIRQPending1 <= 0;
1219
        sprSprCollision1 <= 0;
1220
        sprSprIRQ1 <= 0;
1221
end
1222
else if (sprCollision) begin
1223
        // isFirstCollision
1224
        if ((sprSprCollision1==0)||(cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110010)) begin
1225
                sprSprIRQPending1 <= 1;
1226
                sprSprIRQ1 <= sprSprIe;
1227
                sprSprCollision1 <= sproact;
1228
        end
1229
        else
1230
                sprSprCollision1 <= sprSprCollision1|sproact;
1231
end
1232
else if (cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110010) begin
1233
        sprSprCollision1 <= 0;
1234
        sprSprIRQPending1 <= 0;
1235
        sprSprIRQ1 <= 0;
1236
end
1237
 
1238
 
1239
// Load the sprite background collision register. This register
1240
// continually accumulates collision bits until reset by reading
1241
// the register.
1242
// Set the collision IRQ on the first collision and don't set it
1243
// again until after the collision register has been read.
1244
// Note the background collision indicator is externally supplied,
1245
// it will come from the color processing logic.
1246
always @(posedge vclk)
1247
if (rst_i) begin
1248
        sprBkIRQPending1 <= 0;
1249
        sprBkCollision1 <= 0;
1250
        sprBkIRQ1 <= 0;
1251
end
1252
else if (|bkCollision) begin
1253
        // Is the register being cleared at the same time
1254
        // a collision occurss ?
1255
        // isFirstCollision
1256
        if ((sprBkCollision1==0) || (cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110011)) begin
1257
                sprBkIRQ1 <= sprBkIe;
1258
                sprBkCollision1 <= bkCollision;
1259
                sprBkIRQPending1 <= 1;
1260
        end
1261
        else
1262
                sprBkCollision1 <= sprBkCollision1|bkCollision;
1263
end
1264
else if (cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110011) begin
1265
        sprBkCollision1 <= 0;
1266
        sprBkIRQPending1 <= 0;
1267
        sprBkIRQ1 <= 0;
1268
end
1269
 
1270
endmodule
1271
 
1272
/*
1273
module SpriteRam32 (
1274
        clka, adra, dia, doa, cea, wea,
1275
        clkb, adrb, dib, dob, ceb, web
1276
);
1277
input clka;
1278
input [9:0] adra;
1279
input [31:0] dia;
1280
output [31:0] doa;
1281
input cea;
1282
input wea;
1283
input clkb;
1284
input [9:0] adrb;
1285
input [31:0] dib;
1286
output [31:0] dob;
1287
input ceb;
1288
input web;
1289
 
1290
reg [31:0] mem [0:1023];
1291
reg [9:0] radra;
1292
reg [9:0] radrb;
1293
 
1294
always @(posedge clka)  if (cea) radra <= adra;
1295
always @(posedge clkb)  if (ceb) radrb <= adrb;
1296
assign doa = mem [radra];
1297
assign dob = mem [radrb];
1298
always @(posedge clka)
1299
        if (cea & wea) mem[adra] <= dia;
1300
always @(posedge clkb)
1301
        if (ceb & web) mem[adrb] <= dib;
1302
 
1303
endmodule
1304
 
1305
*/

powered by: WebSVN 2.1.0

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