pgen.v 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * pgen.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2019 Sylvain Munaut <tnt@246tNt.com>
  7. * All rights reserved.
  8. *
  9. * BSD 3-clause, see LICENSE.bsd
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. * * Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * * Neither the name of the <organization> nor the
  19. * names of its contributors may be used to endorse or promote products
  20. * derived from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25. * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  26. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. `default_nettype none
  34. module pgen #(
  35. parameter integer N_ROWS = 64, // # of rows (must be power of 2!!!)
  36. parameter integer N_COLS = 64, // # of columns
  37. parameter integer BITDEPTH = 24,
  38. // Auto-set
  39. parameter integer LOG_N_ROWS = $clog2(N_ROWS),
  40. parameter integer LOG_N_COLS = $clog2(N_COLS)
  41. )(
  42. // Frame Buffer write interface
  43. output wire [LOG_N_ROWS-1:0] fbw_row_addr,
  44. output wire fbw_row_store,
  45. input wire fbw_row_rdy,
  46. output wire fbw_row_swap,
  47. output wire [BITDEPTH-1:0] fbw_data,
  48. output wire [LOG_N_COLS-1:0] fbw_col_addr,
  49. output wire fbw_wren,
  50. output wire frame_swap,
  51. input wire frame_rdy,
  52. // Clock / Reset
  53. input wire clk,
  54. input wire rst
  55. );
  56. // Signals
  57. // -------
  58. // FSM
  59. localparam
  60. ST_WAIT_FRAME = 0,
  61. ST_GEN_ROW = 1,
  62. ST_WRITE_ROW = 2,
  63. ST_WAIT_ROW = 3;
  64. reg [2:0] fsm_state;
  65. reg [2:0] fsm_state_next;
  66. // Counters
  67. reg [11:0] frame;
  68. reg [LOG_N_ROWS-1:0] cnt_row;
  69. reg [LOG_N_COLS-1:0] cnt_col;
  70. reg cnt_row_last;
  71. reg cnt_col_last;
  72. // Output
  73. wire [7:0] color [0:2];
  74. // FSM
  75. // ---
  76. // State register
  77. always @(posedge clk or posedge rst)
  78. if (rst)
  79. fsm_state <= ST_WAIT_FRAME;
  80. else
  81. fsm_state <= fsm_state_next;
  82. // Next-State logic
  83. always @(*)
  84. begin
  85. // Default is not to move
  86. fsm_state_next = fsm_state;
  87. // Transitions ?
  88. case (fsm_state)
  89. ST_WAIT_FRAME:
  90. if (frame_rdy)
  91. fsm_state_next = ST_GEN_ROW;
  92. ST_GEN_ROW:
  93. if (cnt_col_last)
  94. fsm_state_next = ST_WRITE_ROW;
  95. ST_WRITE_ROW:
  96. if (fbw_row_rdy)
  97. fsm_state_next = cnt_row_last ? ST_WAIT_ROW : ST_GEN_ROW;
  98. ST_WAIT_ROW:
  99. if (fbw_row_rdy)
  100. fsm_state_next = ST_WAIT_FRAME;
  101. endcase
  102. end
  103. // Counters
  104. // --------
  105. // Frame counter
  106. always @(posedge clk or posedge rst)
  107. if (rst)
  108. frame <= 0;
  109. else if ((fsm_state == ST_WAIT_ROW) && fbw_row_rdy)
  110. frame <= frame + 1;
  111. // Row counter
  112. always @(posedge clk)
  113. if (fsm_state == ST_WAIT_FRAME) begin
  114. cnt_row <= 0;
  115. cnt_row_last <= 1'b0;
  116. end else if ((fsm_state == ST_WRITE_ROW) && fbw_row_rdy) begin
  117. cnt_row <= cnt_row + 1;
  118. cnt_row_last <= cnt_row == ((1 << LOG_N_ROWS) - 2);
  119. end
  120. // Column counter
  121. always @(posedge clk)
  122. if (fsm_state != ST_GEN_ROW) begin
  123. cnt_col <= 0;
  124. cnt_col_last <= 0;
  125. end else begin
  126. cnt_col <= cnt_col + 1;
  127. cnt_col_last <= cnt_col == (N_COLS - 2);
  128. end
  129. // Front-Buffer write
  130. // ------------------
  131. // Generate R/B channels by taking 8 bits off the row/col counters
  132. // (and wrapping to the MSBs if those are shorter than 8 bits
  133. genvar i;
  134. generate
  135. for (i=0; i<8; i=i+1)
  136. begin
  137. assign color[0][7-i] = cnt_row[LOG_N_ROWS-1-(i%LOG_N_ROWS)];
  138. assign color[2][7-i] = cnt_col[LOG_N_COLS-1-(i%LOG_N_COLS)];
  139. end
  140. endgenerate
  141. // Moving green lines
  142. wire [3:0] c0 = frame[7:4];
  143. wire [3:0] c1 = frame[7:4] + 1;
  144. wire [3:0] a0 = 4'hf - frame[3:0];
  145. wire [3:0] a1 = frame[3:0];
  146. assign color[1] =
  147. (((cnt_col[3:0] == c0) || (cnt_row[3:0] == c0)) ? {a0, a0} : 8'h00) +
  148. (((cnt_col[3:0] == c1) || (cnt_row[3:0] == c1)) ? {a1, a1} : 8'h00);
  149. // Write enable and address
  150. assign fbw_wren = fsm_state == ST_GEN_ROW;
  151. assign fbw_col_addr = cnt_col;
  152. // Map to color
  153. generate
  154. if (BITDEPTH == 8)
  155. assign fbw_data = { color[2][7:5], color[1][7:5], color[0][7:6] };
  156. else if (BITDEPTH == 16)
  157. assign fbw_data = { color[2][7:3], color[1][7:2], color[0][7:3] };
  158. else if (BITDEPTH == 24)
  159. assign fbw_data = { color[2], color[1], color[0] };
  160. endgenerate
  161. // Back-Buffer store
  162. // -----------------
  163. assign fbw_row_addr = cnt_row;
  164. assign fbw_row_store = (fsm_state == ST_WRITE_ROW) && fbw_row_rdy;
  165. assign fbw_row_swap = (fsm_state == ST_WRITE_ROW) && fbw_row_rdy;
  166. // Next frame
  167. // ----------
  168. assign frame_swap = (fsm_state == ST_WAIT_ROW) && fbw_row_rdy;
  169. endmodule // pgen