1
0

Spriterenderer.v 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /*
  2. * Renders Background and Window plane
  3. */
  4. module Spriterenderer
  5. #(
  6. parameter H_RES = 320, // horizontal resolution (pixels)
  7. parameter V_RES = 200, // vertical resolution (lines)
  8. parameter H_FP = 34, // horizontal front porch
  9. parameter H_SYNC = 32, // horizontal sync
  10. parameter H_BP = 56, // horizontal back porch
  11. parameter V_FP = 23, // vertical front porch
  12. parameter V_SYNC = 5, // vertical sync
  13. parameter V_BP = 34, // vertical back porch
  14. parameter H_POL = 0, // horizontal sync polarity (0:neg, 1:pos)
  15. parameter V_POL = 0 // vertical sync polarity
  16. )
  17. (
  18. //VGA I/O
  19. input vga_clk, //9MHz
  20. input vga_hs,
  21. input vga_vs,
  22. output wire [2:0] vga_r,
  23. output wire [2:0] vga_g,
  24. output wire [1:0] vga_b,
  25. input [9:0] h_count, // line position in pixels including blanking
  26. input [8:0] v_count, // frame position in lines including blanking
  27. input o_hs,
  28. input o_vs,
  29. input o_h,
  30. input o_v,
  31. input o_frame,
  32. //VRAM32
  33. output [13:0] vram32_addr,
  34. input [31:0] vram32_q,
  35. //VRAMSPR
  36. output [13:0] vramSPR_addr,
  37. input [8:0] vramSPR_q,
  38. //Draw pixel signal
  39. output wire draw_sprite,
  40. output wire draw_behind_bg
  41. );
  42. //x: 9b
  43. //y: 8b
  44. //tile: 8b
  45. //palette: 5b
  46. //hflip: 1b
  47. //vflip: 1b
  48. //priority: 1b
  49. //disable : 1b
  50. //------------ +
  51. // 34b
  52. wire o_de;
  53. assign o_de = h_count > HA_STA & h_count <= HA_END
  54. & v_count > VA_STA & v_count <= VA_END;
  55. parameter MAX_SPRITES = 16;
  56. //currently two sprites
  57. reg [33:0] sprites [0:MAX_SPRITES-1];
  58. reg [33:0] sprites_next [0:MAX_SPRITES-1];
  59. reg [5:0] spriteIdx = 0;
  60. reg [9:0] h_count_delay;
  61. reg [9:0] h_count_visible_delay;
  62. reg [8:0] v_count_delay;
  63. reg [8:0] v_count_visible_delay;
  64. always @(negedge vga_clk)
  65. begin
  66. h_count_delay <= h_count;
  67. v_count_delay <= v_count;
  68. h_count_visible_delay <= h_count_visible;
  69. v_count_visible_delay <= v_count_visible;
  70. end
  71. reg [5:0] spriteSelectionList [0:MAX_SPRITES-1];
  72. reg [5:0] spriteSelectionCount;
  73. //select for next line during h_count_visible (delay)
  74. integer x=0;
  75. always @(posedge vga_clk)
  76. begin
  77. if (h_count_visible_delay == 319) //do somewhere at end of hline
  78. begin
  79. spriteSelectionCount <= 6'd0;
  80. for (x=0; x<MAX_SPRITES; x=x+1)
  81. begin
  82. spriteSelectionList[x] <= 6'd0;
  83. end
  84. end
  85. else
  86. begin
  87. if (v_count_visible_delay < 240 || v_count_visible_delay == 511)
  88. begin
  89. if (spriteSelectionCount < MAX_SPRITES)
  90. begin
  91. if (h_count_visible_delay < 64)
  92. begin
  93. if ((v_count_visible_delay + 1) >= vramSPR_q && (v_count_visible_delay + 1) < vramSPR_q + 8)
  94. begin
  95. spriteSelectionList[spriteSelectionCount] <= h_count_visible_delay;
  96. spriteSelectionCount <= spriteSelectionCount + 1'b1;
  97. end
  98. end
  99. end
  100. end
  101. end
  102. end
  103. assign vramSPR_addr = (v_count_visible != 511 && v_count_visible > 239) ? 15'd0:
  104. (h_count_visible >= 0 && h_count_visible < 128) ? (h_count_visible * 4) + 1'b1:
  105. (spriteSelectionList[(h_count_visible-128)>>2]<<2) + h_count_visible[1:0];
  106. integer v=0;
  107. always @(posedge vga_clk)
  108. begin
  109. if (h_count_visible_delay == 127) //right before writing the sprites
  110. begin
  111. for (v=0; v<MAX_SPRITES; v=v+1)
  112. begin
  113. sprites_next[v] <= 34'd0;
  114. end
  115. end
  116. else
  117. begin
  118. if (h_count_visible_delay >= 128 && h_count_visible_delay < 192)
  119. begin
  120. case (h_count_visible_delay[1:0])
  121. 2'd0 : sprites_next[(h_count_visible_delay-128)/4][33:25] <= vramSPR_q[8:0];
  122. 2'd1 : sprites_next[(h_count_visible_delay-128)/4][24:17] <= vramSPR_q[7:0];
  123. 2'd2 : sprites_next[(h_count_visible_delay-128)/4][16:9] <= vramSPR_q[7:0];
  124. 2'd3 : sprites_next[(h_count_visible_delay-128)/4][8:0] <= vramSPR_q[8:0];
  125. endcase
  126. end
  127. end
  128. end
  129. integer b=0;
  130. always @(posedge vga_clk)
  131. begin
  132. if (h_count_visible_delay == 319)
  133. begin
  134. for (b=0; b<MAX_SPRITES; b=b+1)
  135. begin
  136. sprites[b] <= sprites_next[b];
  137. end
  138. end
  139. end
  140. // Horizontal: sync, active, and pixels
  141. localparam HS_STA = H_FP - 1; // sync start (first pixel is 0)
  142. localparam HS_END = HS_STA + H_SYNC; // sync end
  143. localparam HA_STA = HS_END + H_BP; // active start
  144. localparam HA_END = HA_STA + H_RES; // active end
  145. localparam LINE = HA_END; // line pixels
  146. // Vertical: sync, active, and pixels
  147. localparam VS_STA = V_FP - 1; // sync start (first line is 0)
  148. localparam VS_END = VS_STA + V_SYNC; // sync end
  149. localparam VA_STA = VS_END + V_BP; // active start
  150. localparam VA_END = VA_STA + V_RES; // active end
  151. localparam FRAME = VA_END; // frame lines
  152. // counters for tile and position
  153. wire [8:0] v_count_visible;
  154. assign v_count_visible = v_count - V_FP - V_SYNC - V_BP;
  155. wire [9:0] h_count_visible;
  156. assign h_count_visible = h_count - H_FP - H_SYNC - H_BP;
  157. wire [5:0] h_tile;
  158. assign h_tile = (h_count_visible / 8);
  159. wire [5:0] v_tile;
  160. assign v_tile = v_count_visible / 8;
  161. wire [2:0] h_tile_pixel;
  162. assign h_tile_pixel = h_count_visible[2:0];
  163. wire [2:0] v_tile_pixel;
  164. assign v_tile_pixel = v_count_visible[2:0];
  165. wire [10:0] tile;
  166. assign tile = (v_tile * (H_RES/8)) + h_tile;
  167. wire [5:0] h_tile_next;
  168. assign h_tile_next = ((h_count - H_FP - H_SYNC - H_BP + 8) / 8);
  169. wire [10:0] tile_next;
  170. assign tile_next = (v_tile * (H_RES/8)) + h_tile_next;
  171. wire [3:0] spriteVpixel [0:MAX_SPRITES-1];
  172. wire [3:0] spriteHpixel [0:MAX_SPRITES-1];
  173. genvar l;
  174. generate
  175. for (l=0; l<MAX_SPRITES; l=l+1) begin:o
  176. assign spriteVpixel[l] = (v_count_visible - sprites[l][24:17]);
  177. assign spriteHpixel[l] = (h_count_visible - sprites[l][33:25]);
  178. end
  179. endgenerate
  180. wire [9:0] h_count_div2;
  181. assign h_count_div2 = h_count >> 1;
  182. reg [9:0] h_count_div2_offset;
  183. always @(negedge vga_clk)
  184. begin
  185. h_count_div2_offset <= h_count_div2;
  186. end
  187. wire [5:0] spritephase;
  188. reg [5:0] spritephaseOffset;
  189. always @(negedge vga_clk)
  190. begin
  191. spritephaseOffset <= spritephase;
  192. end
  193. assign spritephase = (v_count_visible >= 240) ? 0:
  194. (h_count >= MAX_SPRITES*2) ? 0:
  195. (h_count[0] == 0) ? 1:
  196. (h_count[0] == 1) ? 2:
  197. 0;
  198. wire spriteVisible [0:MAX_SPRITES-1];
  199. genvar m;
  200. generate
  201. for (m=0; m<MAX_SPRITES; m=m+1) begin:p
  202. assign spriteVisible[m] = ( h_count_visible >= sprites[m][33:25] && h_count_visible < sprites[m][33:25] + 8 && v_count_visible >= sprites[m][24:17] && v_count_visible < sprites[m][24:17] + 8);
  203. end
  204. endgenerate
  205. //For reversing the tile data
  206. wire [31:0] vram32_q_reverse;
  207. genvar i;
  208. generate
  209. for (i=0; i<=31; i=i+1) begin:y
  210. assign vram32_q_reverse[31-i] = vram32_q[i];
  211. end
  212. endgenerate
  213. reg [63:0] rendered_sprite [0:MAX_SPRITES-1];
  214. reg [15:0] pattern;
  215. reg [31:0] palette;
  216. always @(posedge vga_clk)
  217. begin
  218. if (spritephaseOffset == 1)
  219. begin
  220. //get pattern
  221. if (spriteVpixel[h_count_div2_offset][0] == 1)
  222. pattern <= vram32_q_reverse[31:16];
  223. else
  224. pattern <= vram32_q_reverse[15:0];
  225. end
  226. if (spritephaseOffset == 2)
  227. begin
  228. //get color
  229. palette <= vram32_q;
  230. case (pattern[1:0])
  231. 2'b00: rendered_sprite[h_count_div2_offset][7:0] <= vram32_q[31:24];
  232. 2'b01: rendered_sprite[h_count_div2_offset][7:0] <= vram32_q[23:16];
  233. 2'b10: rendered_sprite[h_count_div2_offset][7:0] <= vram32_q[15:8];
  234. 2'b11: rendered_sprite[h_count_div2_offset][7:0] <= vram32_q[7:0];
  235. endcase
  236. case (pattern[3:2])
  237. 2'b00: rendered_sprite[h_count_div2_offset][15:8] <= vram32_q[31:24];
  238. 2'b01: rendered_sprite[h_count_div2_offset][15:8] <= vram32_q[23:16];
  239. 2'b10: rendered_sprite[h_count_div2_offset][15:8] <= vram32_q[15:8];
  240. 2'b11: rendered_sprite[h_count_div2_offset][15:8] <= vram32_q[7:0];
  241. endcase
  242. case (pattern[5:4])
  243. 2'b00: rendered_sprite[h_count_div2_offset][23:16] <= vram32_q[31:24];
  244. 2'b01: rendered_sprite[h_count_div2_offset][23:16] <= vram32_q[23:16];
  245. 2'b10: rendered_sprite[h_count_div2_offset][23:16] <= vram32_q[15:8];
  246. 2'b11: rendered_sprite[h_count_div2_offset][23:16] <= vram32_q[7:0];
  247. endcase
  248. case (pattern[7:6])
  249. 2'b00: rendered_sprite[h_count_div2_offset][31:24] <= vram32_q[31:24];
  250. 2'b01: rendered_sprite[h_count_div2_offset][31:24] <= vram32_q[23:16];
  251. 2'b10: rendered_sprite[h_count_div2_offset][31:24] <= vram32_q[15:8];
  252. 2'b11: rendered_sprite[h_count_div2_offset][31:24] <= vram32_q[7:0];
  253. endcase
  254. case (pattern[9:8])
  255. 2'b00: rendered_sprite[h_count_div2_offset][39:32] <= vram32_q[31:24];
  256. 2'b01: rendered_sprite[h_count_div2_offset][39:32] <= vram32_q[23:16];
  257. 2'b10: rendered_sprite[h_count_div2_offset][39:32] <= vram32_q[15:8];
  258. 2'b11: rendered_sprite[h_count_div2_offset][39:32] <= vram32_q[7:0];
  259. endcase
  260. case (pattern[11:10])
  261. 2'b00: rendered_sprite[h_count_div2_offset][47:40] <= vram32_q[31:24];
  262. 2'b01: rendered_sprite[h_count_div2_offset][47:40] <= vram32_q[23:16];
  263. 2'b10: rendered_sprite[h_count_div2_offset][47:40] <= vram32_q[15:8];
  264. 2'b11: rendered_sprite[h_count_div2_offset][47:40] <= vram32_q[7:0];
  265. endcase
  266. case (pattern[13:12])
  267. 2'b00: rendered_sprite[h_count_div2_offset][55:48] <= vram32_q[31:24];
  268. 2'b01: rendered_sprite[h_count_div2_offset][55:48] <= vram32_q[23:16];
  269. 2'b10: rendered_sprite[h_count_div2_offset][55:48] <= vram32_q[15:8];
  270. 2'b11: rendered_sprite[h_count_div2_offset][55:48] <= vram32_q[7:0];
  271. endcase
  272. case (pattern[15:14])
  273. 2'b00: rendered_sprite[h_count_div2_offset][63:56] <= vram32_q[31:24];
  274. 2'b01: rendered_sprite[h_count_div2_offset][63:56] <= vram32_q[23:16];
  275. 2'b10: rendered_sprite[h_count_div2_offset][63:56] <= vram32_q[15:8];
  276. 2'b11: rendered_sprite[h_count_div2_offset][63:56] <= vram32_q[7:0];
  277. endcase
  278. end
  279. end
  280. assign vram32_addr = (spritephase == 1) ? (sprites[h_count_div2][16:9] * 4) + (spriteVpixel[h_count_div2])/2 :
  281. (spritephase == 2) ? 1024 + sprites[h_count_div2][8:4]:
  282. 14'd0;
  283. //RENDERING
  284. assign draw_sprite = 1'b0;
  285. assign draw_behind_bg = 1'b0;
  286. //Render all sprites
  287. wire [3:0] sprite_r [0:MAX_SPRITES-1];
  288. wire [3:0] sprite_g [0:MAX_SPRITES-1];
  289. wire [2:0] sprite_b [0:MAX_SPRITES-1];
  290. //For generating sprite rgb assignments
  291. genvar j;
  292. generate
  293. for (j=0; j<MAX_SPRITES; j=j+1)
  294. begin:n
  295. assign sprite_r[j] = (!spriteVisible[j]) ? 3'd0:
  296. (spriteHpixel[j] == 0) ? rendered_sprite[j][0*8 +7: 0*8 +5]:
  297. (spriteHpixel[j] == 1) ? rendered_sprite[j][1*8 +7: 1*8 +5]:
  298. (spriteHpixel[j] == 2) ? rendered_sprite[j][2*8 +7: 2*8 +5]:
  299. (spriteHpixel[j] == 3) ? rendered_sprite[j][3*8 +7: 3*8 +5]:
  300. (spriteHpixel[j] == 4) ? rendered_sprite[j][4*8 +7: 4*8 +5]:
  301. (spriteHpixel[j] == 5) ? rendered_sprite[j][5*8 +7: 5*8 +5]:
  302. (spriteHpixel[j] == 6) ? rendered_sprite[j][6*8 +7: 6*8 +5]:
  303. (spriteHpixel[j] == 7) ? rendered_sprite[j][7*8 +7: 7*8 +5]:
  304. 3'd0;
  305. assign sprite_g[j] = (!spriteVisible[j]) ? 3'd0:
  306. (spriteHpixel[j] == 0) ? rendered_sprite[j][0*8 +4: 0*8 +2]:
  307. (spriteHpixel[j] == 1) ? rendered_sprite[j][1*8 +4: 1*8 +2]:
  308. (spriteHpixel[j] == 2) ? rendered_sprite[j][2*8 +4: 2*8 +2]:
  309. (spriteHpixel[j] == 3) ? rendered_sprite[j][3*8 +4: 3*8 +2]:
  310. (spriteHpixel[j] == 4) ? rendered_sprite[j][4*8 +4: 4*8 +2]:
  311. (spriteHpixel[j] == 5) ? rendered_sprite[j][5*8 +4: 5*8 +2]:
  312. (spriteHpixel[j] == 6) ? rendered_sprite[j][6*8 +4: 6*8 +2]:
  313. (spriteHpixel[j] == 7) ? rendered_sprite[j][7*8 +4: 7*8 +2]:
  314. 3'd0;
  315. assign sprite_b[j] = (!spriteVisible[j]) ? 3'd0:
  316. (spriteHpixel[j] == 0) ? rendered_sprite[j][0*8 +1: 0*8 +0]:
  317. (spriteHpixel[j] == 1) ? rendered_sprite[j][1*8 +1: 1*8 +0]:
  318. (spriteHpixel[j] == 2) ? rendered_sprite[j][2*8 +1: 2*8 +0]:
  319. (spriteHpixel[j] == 3) ? rendered_sprite[j][3*8 +1: 3*8 +0]:
  320. (spriteHpixel[j] == 4) ? rendered_sprite[j][4*8 +1: 4*8 +0]:
  321. (spriteHpixel[j] == 5) ? rendered_sprite[j][5*8 +1: 5*8 +0]:
  322. (spriteHpixel[j] == 6) ? rendered_sprite[j][6*8 +1: 6*8 +0]:
  323. (spriteHpixel[j] == 7) ? rendered_sprite[j][7*8 +1: 7*8 +0]:
  324. 2'd0;
  325. end
  326. endgenerate
  327. //Select which pixel to render
  328. wire sprite_drawn [0:MAX_SPRITES-1];
  329. genvar k;
  330. generate
  331. for (k=0; k<MAX_SPRITES; k=k+1)
  332. begin:z
  333. assign sprite_drawn[k] = (sprite_r[k] != 3'd0 || sprite_g[k] != 3'd0 || sprite_b[k] != 2'd0) ? 1'b1:
  334. 1'b0;
  335. end
  336. endgenerate
  337. assign vga_r = (sprite_drawn[0]) ? sprite_r[0]:
  338. (sprite_drawn[1]) ? sprite_r[1]:
  339. (sprite_drawn[2]) ? sprite_r[2]:
  340. (sprite_drawn[3]) ? sprite_r[3]:
  341. (sprite_drawn[4]) ? sprite_r[4]:
  342. (sprite_drawn[5]) ? sprite_r[5]:
  343. (sprite_drawn[6]) ? sprite_r[6]:
  344. (sprite_drawn[7]) ? sprite_r[7]:
  345. (sprite_drawn[8]) ? sprite_r[8]:
  346. (sprite_drawn[9]) ? sprite_r[9]:
  347. (sprite_drawn[10]) ? sprite_r[10]:
  348. (sprite_drawn[11]) ? sprite_r[11]:
  349. (sprite_drawn[12]) ? sprite_r[12]:
  350. (sprite_drawn[13]) ? sprite_r[13]:
  351. (sprite_drawn[14]) ? sprite_r[14]:
  352. (sprite_drawn[15]) ? sprite_r[15]:
  353. 3'd0;
  354. assign vga_g = (sprite_drawn[0]) ? sprite_g[0]:
  355. (sprite_drawn[1]) ? sprite_g[1]:
  356. (sprite_drawn[2]) ? sprite_g[2]:
  357. (sprite_drawn[3]) ? sprite_g[3]:
  358. (sprite_drawn[4]) ? sprite_g[4]:
  359. (sprite_drawn[5]) ? sprite_g[5]:
  360. (sprite_drawn[6]) ? sprite_g[6]:
  361. (sprite_drawn[7]) ? sprite_g[7]:
  362. (sprite_drawn[8]) ? sprite_g[8]:
  363. (sprite_drawn[9]) ? sprite_g[9]:
  364. (sprite_drawn[10]) ? sprite_g[10]:
  365. (sprite_drawn[11]) ? sprite_g[11]:
  366. (sprite_drawn[12]) ? sprite_g[12]:
  367. (sprite_drawn[13]) ? sprite_g[13]:
  368. (sprite_drawn[14]) ? sprite_g[14]:
  369. (sprite_drawn[15]) ? sprite_g[15]:
  370. 3'd0;
  371. assign vga_b = (sprite_drawn[0]) ? sprite_b[0]:
  372. (sprite_drawn[1]) ? sprite_b[1]:
  373. (sprite_drawn[2]) ? sprite_b[2]:
  374. (sprite_drawn[3]) ? sprite_b[3]:
  375. (sprite_drawn[4]) ? sprite_b[4]:
  376. (sprite_drawn[5]) ? sprite_b[5]:
  377. (sprite_drawn[6]) ? sprite_b[6]:
  378. (sprite_drawn[7]) ? sprite_b[7]:
  379. (sprite_drawn[8]) ? sprite_b[8]:
  380. (sprite_drawn[9]) ? sprite_b[9]:
  381. (sprite_drawn[10]) ? sprite_b[10]:
  382. (sprite_drawn[11]) ? sprite_b[11]:
  383. (sprite_drawn[12]) ? sprite_b[12]:
  384. (sprite_drawn[13]) ? sprite_b[13]:
  385. (sprite_drawn[14]) ? sprite_b[14]:
  386. (sprite_drawn[15]) ? sprite_b[15]:
  387. 2'd0;
  388. endmodule