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

Subversion Repositories rtf_sprite_controller

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rtf_sprite_controller
    from Rev 8 to Rev 9
    Reverse comparison

Rev 8 → Rev 9

/trunk/rtl/verilog/cntpop.v
0,0 → 1,445
// ============================================================================
// __
// \\__/ o\ (C) 2006-2020 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// cntpop.v
// - count number of one bits in a byte
// - simple fast approach - lookup table
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ============================================================================
 
module cntpop8(
input [7:0] i,
output reg [3:0] o
);
 
always @(i)
case (i)
8'b00000000: o = 0;
8'b00000001: o = 1;
8'b00000010: o = 1;
8'b00000011: o = 2;
8'b00000100: o = 1;
8'b00000101: o = 2;
8'b00000110: o = 2;
8'b00000111: o = 3;
8'b00001000: o = 1;
8'b00001001: o = 2;
8'b00001010: o = 2;
8'b00001011: o = 3;
8'b00001100: o = 2;
8'b00001101: o = 3;
8'b00001110: o = 3;
8'b00001111: o = 4;
8'b00010000: o = 1;
8'b00010001: o = 2;
8'b00010010: o = 2;
8'b00010011: o = 3;
8'b00010100: o = 2;
8'b00010101: o = 3;
8'b00010110: o = 3;
8'b00010111: o = 4;
8'b00011000: o = 2;
8'b00011001: o = 3;
8'b00011010: o = 3;
8'b00011011: o = 4;
8'b00011100: o = 3;
8'b00011101: o = 4;
8'b00011110: o = 4;
8'b00011111: o = 5;
8'b00100000: o = 1;
8'b00100001: o = 2;
8'b00100010: o = 2;
8'b00100011: o = 3;
8'b00100100: o = 2;
8'b00100101: o = 3;
8'b00100110: o = 3;
8'b00100111: o = 4;
8'b00101000: o = 2;
8'b00101001: o = 3;
8'b00101010: o = 3;
8'b00101011: o = 4;
8'b00101100: o = 3;
8'b00101101: o = 4;
8'b00101110: o = 4;
8'b00101111: o = 5;
8'b00110000: o = 2;
8'b00110001: o = 3;
8'b00110010: o = 3;
8'b00110011: o = 4;
8'b00110100: o = 3;
8'b00110101: o = 4;
8'b00110110: o = 4;
8'b00110111: o = 5;
8'b00111000: o = 3;
8'b00111001: o = 4;
8'b00111010: o = 4;
8'b00111011: o = 5;
8'b00111100: o = 4;
8'b00111101: o = 5;
8'b00111110: o = 5;
8'b00111111: o = 6;
// 44 - 1
8'b01000000: o = 1;
8'b01000001: o = 2;
8'b01000010: o = 2;
8'b01000011: o = 3;
8'b01000100: o = 2;
8'b01000101: o = 3;
8'b01000110: o = 3;
8'b01000111: o = 4;
8'b01001000: o = 2;
8'b01001001: o = 3;
8'b01001010: o = 3;
8'b01001011: o = 4;
8'b01001100: o = 3;
8'b01001101: o = 4;
8'b01001110: o = 4;
8'b01001111: o = 5;
 
8'b01010000: o = 2;
8'b01010001: o = 3;
8'b01010010: o = 3;
8'b01010011: o = 4;
8'b01010100: o = 3;
8'b01010101: o = 4;
8'b01010110: o = 4;
8'b01010111: o = 5;
8'b01011000: o = 3;
8'b01011001: o = 4;
8'b01011010: o = 4;
8'b01011011: o = 5;
8'b01011100: o = 4;
8'b01011101: o = 5;
8'b01011110: o = 5;
8'b01011111: o = 6;
8'b01100000: o = 2;
8'b01100001: o = 3;
8'b01100010: o = 3;
8'b01100011: o = 4;
8'b01100100: o = 3;
8'b01100101: o = 4;
8'b01100110: o = 4;
8'b01100111: o = 5;
8'b01101000: o = 3;
8'b01101001: o = 4;
8'b01101010: o = 4;
8'b01101011: o = 5;
8'b01101100: o = 4;
8'b01101101: o = 5;
8'b01101110: o = 5;
8'b01101111: o = 6;
8'b01110000: o = 3;
8'b01110001: o = 4;
8'b01110010: o = 4;
8'b01110011: o = 5;
8'b01110100: o = 4;
8'b01110101: o = 5;
8'b01110110: o = 5;
8'b01110111: o = 6;
8'b01111000: o = 4;
8'b01111001: o = 5;
8'b01111010: o = 5;
8'b01111011: o = 6;
8'b01111100: o = 5;
8'b01111101: o = 6;
8'b01111110: o = 6;
8'b01111111: o = 7;
 
// - 2
8'b10000000: o = 1;
8'b10000001: o = 2;
8'b10000010: o = 2;
8'b10000011: o = 3;
8'b10000100: o = 2;
8'b10000101: o = 3;
8'b10000110: o = 3;
8'b10000111: o = 4;
8'b10001000: o = 2;
8'b10001001: o = 3;
8'b10001010: o = 3;
8'b10001011: o = 4;
8'b10001100: o = 3;
8'b10001101: o = 4;
8'b10001110: o = 4;
8'b10001111: o = 5;
 
8'b10010000: o = 2;
8'b10010001: o = 3;
8'b10010010: o = 3;
8'b10010011: o = 4;
8'b10010100: o = 3;
8'b10010101: o = 4;
8'b10010110: o = 4;
8'b10010111: o = 5;
8'b10011000: o = 3;
8'b10011001: o = 4;
8'b10011010: o = 4;
8'b10011011: o = 5;
8'b10011100: o = 4;
8'b10011101: o = 5;
8'b10011110: o = 5;
8'b10011111: o = 6;
8'b10100000: o = 2;
8'b10100001: o = 3;
8'b10100010: o = 3;
8'b10100011: o = 4;
8'b10100100: o = 3;
8'b10100101: o = 4;
8'b10100110: o = 4;
8'b10100111: o = 5;
8'b10101000: o = 3;
8'b10101001: o = 4;
8'b10101010: o = 4;
8'b10101011: o = 5;
8'b10101100: o = 4;
8'b10101101: o = 5;
8'b10101110: o = 5;
8'b10101111: o = 6;
8'b10110000: o = 3;
8'b10110001: o = 4;
8'b10110010: o = 4;
8'b10110011: o = 5;
8'b10110100: o = 4;
8'b10110101: o = 5;
8'b10110110: o = 5;
8'b10110111: o = 6;
8'b10111000: o = 4;
8'b10111001: o = 5;
8'b10111010: o = 5;
8'b10111011: o = 6;
8'b10111100: o = 5;
8'b10111101: o = 6;
8'b10111110: o = 6;
8'b10111111: o = 7;
// 44 - 3
8'b11000000: o = 2;
8'b11000001: o = 3;
8'b11000010: o = 3;
8'b11000011: o = 4;
8'b11000100: o = 3;
8'b11000101: o = 4;
8'b11000110: o = 4;
8'b11000111: o = 5;
8'b11001000: o = 3;
8'b11001001: o = 4;
8'b11001010: o = 4;
8'b11001011: o = 5;
8'b11001100: o = 4;
8'b11001101: o = 5;
8'b11001110: o = 5;
8'b11001111: o = 6;
8'b11010000: o = 3;
8'b11010001: o = 4;
8'b11010010: o = 4;
8'b11010011: o = 5;
8'b11010100: o = 4;
8'b11010101: o = 5;
8'b11010110: o = 5;
8'b11010111: o = 6;
8'b11011000: o = 4;
8'b11011001: o = 5;
8'b11011010: o = 5;
8'b11011011: o = 6;
8'b11011100: o = 5;
8'b11011101: o = 6;
8'b11011110: o = 6;
8'b11011111: o = 7;
8'b11100000: o = 3;
8'b11100001: o = 4;
8'b11100010: o = 4;
8'b11100011: o = 5;
8'b11100100: o = 4;
8'b11100101: o = 5;
8'b11100110: o = 5;
8'b11100111: o = 6;
8'b11101000: o = 4;
8'b11101001: o = 5;
8'b11101010: o = 5;
8'b11101011: o = 6;
8'b11101100: o = 5;
8'b11101101: o = 6;
8'b11101110: o = 6;
8'b11101111: o = 7;
8'b11110000: o = 4;
8'b11110001: o = 5;
8'b11110010: o = 5;
8'b11110011: o = 6;
8'b11110100: o = 5;
8'b11110101: o = 6;
8'b11110110: o = 6;
8'b11110111: o = 7;
8'b11111000: o = 5;
8'b11111001: o = 6;
8'b11111010: o = 6;
8'b11111011: o = 7;
8'b11111100: o = 6;
8'b11111101: o = 7;
8'b11111110: o = 7;
8'b11111111: o = 8;
 
endcase
 
endmodule
 
 
module cntpop16(
input [15:0] i,
output [4:0] o
);
 
wire [3:0] cnt1, cnt2;
 
cntpop8 u1 (i[ 7:0],cnt1);
cntpop8 u2 (i[15:8],cnt2);
 
assign o = cnt1 + cnt2;
 
endmodule
 
 
// 76 slices / 147 LUTs / 19 ns
module cntpop32(
input [31:0] i,
output [5:0] o
);
 
wire [3:0] cnt1, cnt2, cnt3, cnt4;
 
// cntpop8 results in faster result than cntpop16
cntpop8 u1 (i[ 7: 0],cnt1);
cntpop8 u2 (i[15: 8],cnt2);
cntpop8 u3 (i[23:16],cnt3);
cntpop8 u4 (i[31:24],cnt4);
 
assign o = cnt1+cnt2+cnt3+cnt4;
 
endmodule
 
 
// 156 slices / 300 LUTs / 22.2 ns
module cntpop64(
input [63:0] i,
output [6:0] o
);
 
wire [4:0] cnt1, cnt2, cnt3, cnt4;
 
cntpop16 u1 (i[15: 0],cnt1);
cntpop16 u2 (i[31:16],cnt2);
cntpop16 u3 (i[47:32],cnt3);
cntpop16 u4 (i[63:48],cnt4);
 
assign o = cnt1+cnt2+cnt3+cnt4;
 
endmodule
 
module cntpop80(
input [79:0] i,
output [6:0] o
);
 
wire [4:0] cnt1, cnt2, cnt3, cnt4, cnt5;
 
cntpop16 u1 (i[15: 0],cnt1);
cntpop16 u2 (i[31:16],cnt2);
cntpop16 u3 (i[47:32],cnt3);
cntpop16 u4 (i[63:48],cnt4);
cntpop16 u5 (i[79:64],cnt5);
 
assign o = cnt1+cnt2+cnt3+cnt4+cnt5;
 
endmodule
 
module cntpop128(
input [127:0] i,
output [7:0] o
);
 
wire [6:0] cnt1, cnt2;
 
cntpop64 u1 (i[63: 0],cnt1);
cntpop64 u2 (i[127:64],cnt2);
 
assign o = cnt1+cnt2;
 
endmodule
 
 
module cntpop16reg (
input clk,
input ce,
input [15:0] i,
output reg [4:0] o
);
 
wire [3:0] cnt1, cnt2;
 
cntpop8 u1 (i[ 7:0],cnt1);
cntpop8 u2 (i[15:8],cnt2);
 
always @(posedge clk)
if (ce) o <= cnt1 + cnt2;
 
endmodule
 
module cntpop64reg(
input clk,
input ce,
input [63:0] i,
output reg [6:0] o
);
 
wire [4:0] cnt1, cnt2, cnt3, cnt4;
 
cntpop16reg u1 (clk, ce, i[15: 0],cnt1);
cntpop16reg u2 (clk, ce, i[31:16],cnt2);
cntpop16reg u3 (clk, ce, i[47:32],cnt3);
cntpop16reg u4 (clk, ce, i[63:48],cnt4);
 
always @(posedge clk)
if (ce) o <= cnt1+cnt2+cnt3+cnt4;
 
endmodule
/trunk/rtl/verilog/rfSpriteController.sv
137,6 → 137,7
// 3EC: BC [29:0] background color
// 3FC: ADDR [31:0] sprite DMA address bits [63:32]
//
// 7200
//=============================================================================
 
import wishbone_pkg::*;
261,6 → 262,7
wire [31:0] sprOut4 [pnSprm:0]; // sprite image data output
reg [31:0] sprOut [pnSprm:0]; // sprite image data output
reg [31:0] sprOut5 [pnSprm:0]; // sprite image data output
wire [5:0] actcnt; // count of sprites active at a given pixel location of the screen
 
// Animation
reg [11:0] sprFrameSize [pnSprm:0];
270,6 → 272,7
reg [9:0] sprCurRateCount [pnSprm:0];
reg [pnSprm:0] sprEnableAnimation;
reg [pnSprm:0] sprAutoRepeat;
reg [11:0] sprFrameProd [pnSprm:0];
 
// DMA access
reg [31:12] sprSysAddr [pnSprm:0]; // system memory address of sprite image (low bits)
322,6 → 325,7
 
assign wbm_req.bte = LINEAR;
assign wbm_req.cti = CLASSIC;
assign wbm_req.blen = 6'd63;
assign wbm_req.stb = wbm_req.cyc;
assign wbm_req.sel = 16'hFFFF;
assign wbm_req.cid = 4'd5;
336,8 → 340,19
wire pe_m_ack_i;
edge_det ued2 (.rst(rst_i), .clk(m_clk_i), .ce(1'b1), .i(wbm_resp.ack), .pe(pe_m_ack_i), .ne(), .ee());
 
reg [11:0] tocnt;
always_ff @(posedge m_clk_i)
if (rst_i)
tocnt <= 'd0;
else begin
if (wbm_req.cyc)
tocnt <= tocnt + 2'd1;
else
tocnt <= 'd0;
end
 
always_ff @(posedge m_clk_i)
if (rst_i)
mstate <= IDLE;
else begin
case(mstate)
347,7 → 362,7
ACTIVE:
mstate <= ACK;
ACK:
if (wbm_resp.ack | wbm_resp.err)
if (wbm_resp.ack | wbm_resp.err | tocnt[10])
mstate <= NACK;
NACK:
if (~(wbm_resp.ack|wbm_resp.err))
391,7 → 406,7
case(mstate)
IDLE:
for (n32 = pnSprm; n32 >= 0; n32 = n32 - 1)
if (sprDt[n32])
if (sprDt[n32] & ce)
cob <= sprBurstStart[n32];
ACTIVE:
cob <= cob + 2'd2;
412,7 → 427,7
wbm_req.adr <= {sprSysAddr[dmaOwner],cob[8:1],4'h0};
end
ACK:
if (wbm_resp.ack|wbm_resp.err)
if (wbm_resp.ack|wbm_resp.err|tocnt[10])
wb_m_nack();
endcase
end
426,7 → 441,7
 
// generate a write enable strobe for the sprite image memory
integer n1;
reg [8:0] m_adr_or;
reg [8:0] m_adr_or; // 64-bit value address
reg [127:0] m_dat_ir;
reg ack1;
 
499,7 → 514,7
integer n33;
always_ff @(posedge s_clk_i)
if (rst_i) begin
vSyncT <= 32'hFFFF0000;//FFFFFFFF;
vSyncT <= 32'hFFFFFFFF;//FFFFFFFF;
sprEn <= 32'hFFFFFFFF;
sprDt <= 0;
for (n33 = 0; n33 < pnSpr; n33 = n33 + 1) begin
514,19 → 529,25
hSprPos[n33] <= 200 + (n33 & 7) * 70;
vSprPos[n33] <= 100 + (n33 >> 3) * 100;
sprTc[n33] <= 24'h7FFF; // White 16 bpp
sprWidth[n33] <= 8'd16; // 16x16 sprites
sprHeight[n33] <= 8'd16;
hSprRes[n33] <= 2; // our standard display
vSprRes[n33] <= 2;
sprImageOffs[n33] <= 0;
sprPlane[n33] <= 4'hF;//n[3:0];
sprWidth[n33] <= 8'd24; // 16x16 sprites
sprHeight[n33] <= 8'd21;
hSprRes[n33] <= 2'd2; // our standard display
vSprRes[n33] <= 2'd2;
sprImageOffs[n33] <= 12'h0;
sprPlane[n33] <= 4'h7;//n[3:0];
sprBurstStart[n33] <= 9'h000;
sprBurstEnd[n33] <= 9'h1FE;
sprColorDepth[n33] <= 2'b10;
sprFrameSize[n33] <= 12'd256;
sprFrames[n33] <= 8'd5;
if (n33 >= 5'd29) begin
sprFrameSize[n33] <= 12'd1936;
sprFrames[n33] <= 8'd0;
end
else begin
sprFrameSize[n33] <= 12'd504;
sprFrames[n33] <= 8'd3;
end
sprRate[n33] <= 12'd10;
sprEnableAnimation[n33] <= 1'b1;
sprEnableAnimation[n33] <= n33 < 5'd29;
sprAutoRepeat[n33] <= 1'b1;
end
hSprPos[0] <= 210;
830,15 → 851,20
if (sprCurRateCount[n28] >= sprRate[n28]) begin
sprCurRateCount[n28] <= 'd0;
sprCurFrame[n28] <= sprCurFrame[n28] + 2'd1;
if (sprCurFrame[n28] >= sprFrames[n28])
sprFrameProd[n28] <= sprFrameProd[n28] + sprFrameSize[n28];
if (sprCurFrame[n28] >= sprFrames[n28]) begin
sprCurFrame[n28] <= 'd0;
sprFrameProd[n28] <= 'd0;
end
end
end
else
else begin
sprCurFrame[n28] <= 'd0;
sprFrameProd[n28] <= 'd0;
end
end
end
 
// clock sprite image address counters
integer n8;
always_ff @(posedge vclk)
846,8 → 872,8
// hReset and vReset - top left of sprite,
// reset address to image offset
if (hSprReset[n8] & vSprReset[n8]) begin
sprAddr[n8] <= sprImageOffs[n8] + sprCurFrame[n8] * sprFrameSize[n8];
sprAddrB[n8] <= sprImageOffs[n8] + sprCurFrame[n8] * sprFrameSize[n8];
sprAddr[n8] <= sprImageOffs[n8] + sprFrameProd[n8];
sprAddrB[n8] <= sprImageOffs[n8] + sprFrameProd[n8];
end
// hReset:
// If the next vertical pixel
1059,149 → 1085,14
// same time.
 
//--------------------------------------------------------------------
// Note this case has to be modified for the number of sprites
// ToDo: make collision also depend on plane
//--------------------------------------------------------------------
generate
begin : gSprsColliding
always @(pnSpr or sproact)
if (pnSpr==1)
sprCollision = 0;
else if (pnSpr==2)
case (sproact)
2'b00,
2'b01,
2'b10: sprCollision = 0;
2'b11: sprCollision = 1;
endcase
else if (pnSpr==4)
case (sproact)
4'b0000,
4'b0001,
4'b0010,
4'b0100,
4'b1000: sprCollision = 0;
default: sprCollision = 1;
endcase
else if (pnSpr==6)
case (sproact)
6'b000000,
6'b000001,
6'b000010,
6'b000100,
6'b001000,
6'b010000,
8'b100000: sprCollision = 0;
default: sprCollision = 1;
endcase
else if (pnSpr==8)
case (sproact)
8'b00000000,
8'b00000001,
8'b00000010,
8'b00000100,
8'b00001000,
8'b00010000,
8'b00100000,
8'b01000000,
8'b10000000: sprCollision = 0;
default: sprCollision = 1;
endcase
else if (pnSpr==10)
case (sproact)
10'b0000000000,
10'b0000000001,
10'b0000000010,
10'b0000000100,
10'b0000001000,
10'b0000010000,
10'b0000100000,
10'b0001000000,
10'b0010000000,
10'b0100000000,
10'b1000000000: sprCollision = 0;
default: sprCollision = 1;
endcase
else if (pnSpr==14)
case (sproact)
14'b00000000000000,
14'b00000000000001,
14'b00000000000010,
14'b00000000000100,
14'b00000000001000,
14'b00000000010000,
14'b00000000100000,
14'b00000001000000,
14'b00000010000000,
14'b00000100000000,
14'b00001000000000,
14'b00010000000000,
14'b00100000000000,
14'b01000000000000,
14'b10000000000000: sprCollision = 0;
default: sprCollision = 1;
endcase
else if (pnSpr==16)
case (sproact)
16'h0000,
16'h0001,
16'h0002,
16'h0004,
16'h0008,
16'h0010,
16'h0020,
16'h0040,
16'h0080,
16'h0100,
16'h0200,
16'h0400,
16'h0800,
16'h1000,
16'h2000,
16'h4000,
16'h8000: sprCollision = 0;
default: sprCollision = 1;
endcase
else if (pnSpr==32)
case (sproact)
32'h00000000,
32'h00000001,
32'h00000002,
32'h00000004,
32'h00000008,
32'h00000010,
32'h00000020,
32'h00000040,
32'h00000080,
32'h00000100,
32'h00000200,
32'h00000400,
32'h00000800,
32'h00001000,
32'h00002000,
32'h00004000,
32'h00008000,
32'h00010000,
32'h00020000,
32'h00040000,
32'h00080000,
32'h00100000,
32'h00200000,
32'h00400000,
32'h00800000,
32'h01000000,
32'h02000000,
32'h04000000,
32'h08000000,
32'h10000000,
32'h20000000,
32'h40000000,
32'h80000000: sprCollision = 0;
default: sprCollision = 1;
endcase
end
endgenerate
 
cntpop32 ucntp1 (
.i(sproact),
.o(actcnt)
);
 
// Detect when a sprite-background collision has occurred
integer n31;
always_comb
1219,7 → 1110,7
sprSprCollision1 <= 0;
sprSprIRQ1 <= 0;
end
else if (sprCollision) begin
else if (actcnt > 6'd1) begin
// isFirstCollision
if ((sprSprCollision1==0)||(cs_regs && wb_reqs.sel[0] && wb_reqs.adr[9:2]==8'b11110010)) begin
sprSprIRQPending1 <= 1;

powered by: WebSVN 2.1.0

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