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 4 to Rev 5
- ↔ Reverse comparison
Rev 4 → Rev 5
/trunk/rtl/verilog/rtfSpriteController2.v
22,6 → 22,8
// |
// ============================================================================ |
// |
//`define USE_CLOCK_GATE 1'b1 |
|
`define TRUE 1'b1 |
`define FALSE 1'b0 |
`define HIGH 1'b1 |
28,6 → 30,10
`define LOW 1'b0 |
|
`define ABITS 31:0 |
// The cycle at which it's safe to update the working count and address. |
// A good value is just before the end of the scan, but that depends on |
// display resolution. |
`define SPR_WCA 12'd638 |
|
module rtfSpriteController2(rst_i, clk_i, cs_i, cyc_i, stb_i, ack_o, we_i, sel_i, adr_i, dat_i, dat_o, |
m_clk_i, m_cyc_o, m_stb_o, m_ack_i, m_sel_o, m_adr_o, m_dat_i, |
74,7 → 80,7
wire vclk; |
reg [2:0] state; |
reg [1:0] lowres; |
reg [3:0] flashcnt; |
wire [5:0] flashcnt; |
reg rst_collision; |
reg [31:0] collision, c_collision; |
reg [4:0] spriteno; |
84,11 → 90,13
reg [11:0] sprite_pv [0:31]; |
reg [11:0] sprite_ph [0:31]; |
reg [3:0] sprite_pz [0:31]; |
(* ram_style="distributed" *) |
reg [37:0] sprite_color [0:255]; |
reg [31:0] sprite_on; |
reg [31:0] sprite_on_d1; |
reg [31:0] sprite_on_d2; |
reg [31:0] sprite_on_d3; |
(* ram_style="distributed" *) |
reg [`ABITS] spriteAddr [0:31]; |
reg [`ABITS] spriteWaddr [0:31]; |
reg [15:0] spriteMcnt [0:31]; |
95,25 → 103,25
reg [15:0] spriteWcnt [0:31]; |
reg [63:0] m_spriteBmp [0:31]; |
reg [63:0] spriteBmp [0:31]; |
reg [15:0] spriteColor [0:31]; |
reg [31:0] spriteLink1; |
reg [11:0] spriteColorNdx [0:31]; |
reg [7:0] spriteColorNdx [0:31]; |
|
initial begin |
for (n = 0; n < 256; n = n + 1) begin |
sprite_color[n][31:0] = $urandom; |
sprite_color[n][37:32] = 6'd0;//$urandom & 6'd63; |
sprite_color[n] <= 38'h0000FF1F1F; |
end |
for (n = 0; n < 32; n = n + 1) begin |
sprite_ph[n] <= $urandom%800 + 260; |
sprite_pv[n] <= $urandom%600 + 41; |
sprite_pz[n] <= $urandom%256; |
spriteMcnt[n] <= ($urandom%505 + 5) * 32; |
sprite_ph[n] <= 260 + n * 40; |
sprite_pv[n] <= 41 + n * 20; |
sprite_pz[n] <= 8'h00; |
spriteMcnt[n] <= 60 * 32; |
spriteBmp[n] <= 64'hFFFFFFFFFFFFFFFF; |
end |
end |
|
wire pe_hsync, pe_vsync; |
reg [11:0] hctr, vctr, m_hctr, m_vctr; |
wire [11:0] hctr, vctr; |
reg [11:0] m_hctr, m_vctr; |
|
// Generate acknowledge signal |
wire cs = cs_i & cyc_i & stb_i; |
124,11 → 132,11
rdy2 <= rdy1 & cs; |
always @(posedge clk_i) |
rdy3 <= rdy2 & cs; |
assign ack_o = cs & we_i ? 1'b1 : rdy3; |
assign ack_o = (cs & we_i) ? 1'b1 : rdy3; |
|
(* ram_style="block" *) |
reg [63:0] shadow_ram [0:511]; |
reg [10:0] sradr; |
reg [8:0] sradr; |
always @(posedge clk_i) |
if (cs & we_i) begin |
if (sel_i[0]) shadow_ram[adr_i[11:3]][ 7: 0] <= dat_i; |
153,6 → 161,7
rst_collision <= `FALSE; |
controller_enable <= `TRUE; |
spriteEnable <= 32'hFFFFFFFF; |
spriteLink1 <= 32'h0; |
end |
else begin |
rst_collision <= `FALSE; |
164,7 → 173,7
begin |
if (|sel_i[1:0]) sprite_ph[adr_i[8:4]] <= dat_i[11: 0]; |
if (|sel_i[3:2]) sprite_pv[adr_i[8:4]] <= dat_i[27:16]; |
if ( sel_i[4]) sprite_pz[adr_i[8:4]] <= dat_i[39:32]; |
if ( sel_i[ 4]) sprite_pz[adr_i[8:4]] <= dat_i[39:32]; |
if (|sel_i[7:6]) spriteMcnt[adr_i[8:4]] <= dat_i[63:48]; |
end |
9'b1010_0000_0: spriteEnable <= dat_i[31:0]; |
232,9 → 241,9
MEM_ACCESS: |
if (m_ack_i) begin |
m_cyc_o <= `LOW; |
spriteBmp[spriteno] <= dat_i; |
m_spriteBmp[spriteno] <= dat_i; |
if (test) |
spriteBmp[spriteno] <= 64'hFFFFFFFFFFFFFFFF; |
m_spriteBmp[spriteno] <= 64'h00005555AAAAFFFF; |
end |
NEXT_SPRITE: |
spriteno <= spriteno + 5'd1; |
245,6 → 254,7
always @(posedge clk_i) |
c_collision <= collision; |
|
`ifdef USE_CLOCK_GATE |
BUFHCE ucb1 |
( |
.I(dot_clk_i), |
251,31 → 261,18
.CE(controller_enable), |
.O(vclk) |
); |
`else |
assign vclk = dot_clk_i; |
`endif |
|
edge_det ued1 (.clk(vclk), .ce(1'b1), .i(hsync_i), .pe(pe_hsync), .ne(), .ee()); |
edge_det ued2 (.clk(vclk), .ce(1'b1), .i(vsync_i), .pe(pe_vsync), .ne(), .ee()); |
|
always @(posedge vclk) |
if (rst_i) |
hctr <= 12'd0; |
else begin |
if (pe_hsync) |
hctr <= 12'd0; |
else |
hctr <= hctr + 12'd1; |
end |
VT163 #(12) uhctr (.clk(vclk), .clr_n(!rst_i), .ent(1'b1), .enp(1'b1), .ld_n(!pe_hsync), .d(12'd0), .q(hctr), .rco()); |
VT163 #(12) uvctr (.clk(vclk), .clr_n(!rst_i), .ent(pe_hsync), .enp(1'b1), .ld_n(!pe_vsync), .d(12'd0), .q(vctr), .rco()); |
VT163 # (6) ufctr (.clk(vclk), .clr_n(!rst_i), .ent(pe_vsync), .enp(1'b1), .ld_n(1'b1), .d( 6'd0), .q(flashcnt), .rco()); |
|
always @(posedge vclk) |
if (rst_i) |
vctr <= 12'd0; |
else begin |
if (pe_vsync) |
vctr <= 12'd0; |
else if (pe_hsync) |
vctr <= vctr + 12'd1; |
end |
|
always @(posedge vclk) |
begin |
if (rst_collision) |
collision <= 32'd0; |
350,7 → 347,7
2'd2: if ((vctr[11:2] == sprite_pv[n]) && (hctr == 12'h005)) spriteWcnt[n] <= 16'd0; |
endcase |
// The following assumes there are at least 640 clocks in a scan line. |
if (hctr==12'd638) // must be after image data fetch |
if (hctr==`SPR_WCA) // must be after image data fetch |
if (spriteActive[n]) |
case(lowres) |
2'd0,2'd3: spriteWcnt[n] <= spriteWcnt[n] + 16'd32; |
367,11 → 364,11
2'd1: if ((vctr[11:1] == sprite_pv[n]) && (hctr == 12'h005)) spriteWaddr[n] <= spriteAddr[n]; |
2'd2: if ((vctr[11:2] == sprite_pv[n]) && (hctr == 12'h005)) spriteWaddr[n] <= spriteAddr[n]; |
endcase |
if (hctr==12'd638) // must be after image data fetch |
if (hctr==`SPR_WCA) // must be after image data fetch |
case(lowres) |
2'd0,2'd3: spriteWaddr[n] <= spriteWaddr[n] + 32'd16; |
2'd1: if (vctr[0]) spriteWaddr[n] <= spriteWaddr[n] + 32'd16; |
2'd2: if (vctr[1:0]==2'b11) spriteWaddr[n] <= spriteWaddr[n] + 32'd16; |
2'd0,2'd3: spriteWaddr[n] <= spriteWaddr[n] + 32'd8; |
2'd1: if (vctr[0]) spriteWaddr[n] <= spriteWaddr[n] + 32'd8; |
2'd2: if (vctr[1:0]==2'b11) spriteWaddr[n] <= spriteWaddr[n] + 32'd8; |
endcase |
end |
|
403,25 → 400,23
if (hctr==12'h5) |
for (n = 0; n < NSPR; n = n + 1) |
spriteBmp[n] <= m_spriteBmp[n]; |
for (n = 0; n < NSPR; n = n + 1) |
if (spriteShift[n]) |
case(lowres) |
2'd0,2'd3: spriteBmp[n] <= {spriteBmp[n][61:0],2'h0}; |
2'd1: if (hctr[0]) spriteBmp[n] <= {spriteBmp[n][61:0],2'h0}; |
2'd2: if (&hctr[1:0]) spriteBmp[n] <= {spriteBmp[n][61:0],2'h0}; |
endcase |
for (n = 0; n < NSPR; n = n + 1) |
if (spriteShift[n]) |
case(lowres) |
2'd0,2'd3: spriteBmp[n] <= {spriteBmp[n][61:0],2'h0}; |
2'd1: if (hctr[0]) spriteBmp[n] <= {spriteBmp[n][61:0],2'h0}; |
2'd2: if (&hctr[1:0]) spriteBmp[n] <= {spriteBmp[n][61:0],2'h0}; |
endcase |
end |
|
always @(posedge vclk) |
for (n = 0; n < NSPR; n = n + 1) |
if (spriteLink1[n]) begin |
if (spriteLink1[n]) |
spriteColorNdx[n] <= {n[3:0],spriteBmp[(n+1)&31][63:62],spriteBmp[n][63:62]}; |
end |
else if (spriteLink1[(n-1)&31]) begin |
else if (spriteLink1[(n-1)&31]) |
spriteColorNdx[n] <= 8'h00; // transparent |
end |
else |
spriteColorNdx[n] <= {n[4:0],spriteBmp[n][63:62]}; |
spriteColorNdx[n] <= {1'b0,n[4:0],spriteBmp[n][63:62]}; |
|
// Compute index into sprite color palette |
// If none of the sprites are linked, each sprite has it's own set of colors. |
438,8 → 433,8
// The color index from each sprite can be mux'ed into a single value used to |
// access the color palette because output color is a priority chain. This |
// saves having mulriple read ports on the color palette. |
reg [31:0] spriteColorOut2; |
reg [31:0] spriteColorOut3; |
reg [37:0] spriteColorOut2; |
reg [37:0] spriteColorOut3; |
reg [7:0] spriteClrNdx; |
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - |
461,7 → 456,7
|
always @(posedge vclk) |
begin |
sprite_z1 <= 3'h7; |
sprite_z1 <= 8'hff; |
for (n = NSPR-1; n >= 0; n = n -1) |
if (sprite_on[n]) |
sprite_z1 <= sprite_pz[n]; |
490,13 → 485,13
// - - - - - - - - - - - - - - - - - - - - - - - - - - |
// Compute alpha blending |
|
wire [12:0] alphaRed = zrgb_i[23:16] * spriteColorOut2[31:24] + (spriteColorOut2[23:16] * (9'h100 - spriteColorOut2[31:24])); |
wire [12:0] alphaGreen = zrgb_i[15:8] * spriteColorOut2[31:24] + (spriteColorOut2[15:8] * (9'h100 - spriteColorOut2[31:24])); |
wire [12:0] alphaBlue = zrgb_i[7:0] * spriteColorOut2[31:24] + (spriteColorOut2[7:0] * (9'h100 - spriteColorOut2[31:24])); |
wire [15:0] alphaRed = (zrgb_i[23:16] * spriteColorOut2[31:24]) + (spriteColorOut2[23:16] * (9'h100 - spriteColorOut2[31:24])); |
wire [15:0] alphaGreen = (zrgb_i[15:8] * spriteColorOut2[31:24]) + (spriteColorOut2[15:8] * (9'h100 - spriteColorOut2[31:24])); |
wire [15:0] alphaBlue = (zrgb_i[7:0] * spriteColorOut2[31:24]) + (spriteColorOut2[7:0] * (9'h100 - spriteColorOut2[31:24])); |
reg [23:0] alphaOut; |
|
always @(posedge vclk) |
alphaOut <= {alphaRed[12:5],alphaGreen[12:5],alphaBlue[12:5]}; |
alphaOut <= {alphaRed[15:8],alphaGreen[15:8],alphaBlue[15:8]}; |
always @(posedge vclk) |
sprite_z3 <= sprite_z2; |
always @(posedge vclk) |
542,7 → 537,7
|
always @(posedge dot_clk_i) |
case(any_sprite_on4 & controller_enable) |
1'b1: zrgb_o <= {zrgb_i4[31:24],((zb_i4 < sprite_z4) ? zrgb_i4[23:0] : flashOut[23:0])}; |
1'b1: zrgb_o <= (zb_i4 < sprite_z4) ? zrgb_i4 : {sprite_z4,flashOut}; |
1'b0: zrgb_o <= zrgb_i4; |
endcase |
|