top.v 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * top.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 top (
  35. // Button
  36. input wire btn,
  37. // LED
  38. output wire ledr,
  39. output wire ledg,
  40. output wire [2:0] rgb,
  41. // USB
  42. output wire usb_dp,
  43. output wire usb_dn,
  44. output wire usb_pu,
  45. // Clock
  46. input wire clk_in
  47. );
  48. // FSM
  49. // ---
  50. localparam
  51. ST_START = 0,
  52. ST_WAIT = 1,
  53. ST_SEL = 2,
  54. ST_SEL_WAIT = 3,
  55. ST_BOOT = 4;
  56. // Signals
  57. // -------
  58. // Button input
  59. wire btn_iob;
  60. wire btn_v;
  61. wire btn_r;
  62. wire btn_f;
  63. // FSM
  64. reg [2:0] state_nxt;
  65. reg [2:0] state;
  66. // Boot selector
  67. wire boot_now;
  68. reg [1:0] boot_sel;
  69. // Timer/Counter
  70. reg [23:0] timer;
  71. wire timer_tick;
  72. wire timer_rst;
  73. // LED
  74. reg [3:0] dim;
  75. wire [2:0] rgb_pwm;
  76. // Clock / Reset
  77. wire clk;
  78. wire rst;
  79. // Button
  80. // ------
  81. SB_IO #(
  82. .PIN_TYPE(6'b000000),
  83. .PULLUP(1'b1),
  84. .IO_STANDARD("SB_LVCMOS")
  85. ) btn_iob_I (
  86. .PACKAGE_PIN(btn),
  87. .INPUT_CLK(clk),
  88. .D_IN_0(btn_iob)
  89. );
  90. glitch_filter #(
  91. .L(4),
  92. ) btn_flt_I (
  93. .pin_iob_reg(btn_iob),
  94. .cond(1'b1),
  95. .val(btn_v),
  96. .rise(btn_r),
  97. .fall(btn_f),
  98. .clk(clk),
  99. .rst(1'b0) // Ensure the glitch filter has settled
  100. // before logic here engages
  101. );
  102. // State machine
  103. // -------------
  104. // Next state logic
  105. always @(*)
  106. begin
  107. // Default is to stay put
  108. state_nxt <= state;
  109. // Main case
  110. case (state)
  111. ST_START:
  112. // Check for immediate boot
  113. state_nxt <= btn_v ? ST_BOOT : ST_WAIT;
  114. ST_WAIT:
  115. // Wait for first release
  116. if (btn_v == 1'b1)
  117. state_nxt <= ST_SEL;
  118. ST_SEL:
  119. // If button press, temporarily disable it
  120. if (btn_f)
  121. state_nxt <= ST_SEL_WAIT;
  122. // Or wait for timeout
  123. else if (timer_tick)
  124. state_nxt <= ST_BOOT;
  125. ST_SEL_WAIT:
  126. // Wait for button to re-arm
  127. if (timer_tick)
  128. state_nxt <= ST_SEL;
  129. ST_BOOT:
  130. // Nothing to do ... will reconfigure shortly
  131. state_nxt <= state;
  132. endcase
  133. end
  134. // State register
  135. always @(posedge clk or posedge rst)
  136. if (rst)
  137. state <= ST_START;
  138. else
  139. state <= state_nxt;
  140. // Timer
  141. // -----
  142. always @(posedge clk)
  143. if (timer_rst)
  144. timer <= 24'h000000;
  145. else
  146. timer <= timer + 1;
  147. assign timer_rst = (btn_v == 1'b0) | timer_tick;
  148. assign timer_tick = (state == ST_SEL_WAIT) ? timer[15] : timer[23];
  149. // Warm Boot
  150. // ---------
  151. // Boot command
  152. assign boot_now = (state == ST_BOOT);
  153. // Image select
  154. always @(posedge clk or posedge rst)
  155. begin
  156. if (rst)
  157. boot_sel <= 2'b10; // App 1 Image by default
  158. else if (state == ST_WAIT)
  159. boot_sel <= 2'b01; // DFU Image if in select mode
  160. else if (state == ST_SEL)
  161. boot_sel <= boot_sel + btn_f;
  162. end
  163. // IP
  164. SB_WARMBOOT warmboot (
  165. .BOOT(boot_now),
  166. .S0(boot_sel[0]),
  167. .S1(boot_sel[1])
  168. );
  169. // LED
  170. // ---
  171. assign rgb_pwm[0] = dim[3] & ~boot_now & boot_sel[0];
  172. assign rgb_pwm[1] = dim[3] & boot_now;
  173. assign rgb_pwm[2] = dim[3] & ~boot_now & boot_sel[1];
  174. assign ledr = ~boot_sel[0];
  175. assign ledg = ~boot_sel[1];
  176. // Dimming
  177. always @(posedge clk)
  178. if (rst)
  179. dim <= 4'h0;
  180. else
  181. dim <= dim[3] ? 4'h0 : (dim + 1);
  182. // Driver
  183. SB_RGBA_DRV #(
  184. .CURRENT_MODE("0b1"),
  185. .RGB0_CURRENT("0b000001"),
  186. .RGB1_CURRENT("0b000001"),
  187. .RGB2_CURRENT("0b000001")
  188. ) rgb_drv_I (
  189. .RGBLEDEN(1'b1),
  190. .RGB0PWM(rgb_pwm[0]),
  191. .RGB1PWM(rgb_pwm[1]),
  192. .RGB2PWM(rgb_pwm[2]),
  193. .CURREN(1'b1),
  194. .RGB0(rgb[0]),
  195. .RGB1(rgb[1]),
  196. .RGB2(rgb[2])
  197. );
  198. // Dummy USB
  199. // ---------
  200. // (to avoid pullups triggering detection)
  201. SB_IO #(
  202. .PIN_TYPE(6'b101000),
  203. .PULLUP(1'b0),
  204. .IO_STANDARD("SB_LVCMOS")
  205. ) usb[2:0] (
  206. .PACKAGE_PIN({usb_dp, usb_dn, usb_pu}),
  207. .OUTPUT_ENABLE(1'b0),
  208. .D_OUT_0(1'b0)
  209. );
  210. // Clock / Reset
  211. // -------------
  212. reg [7:0] cnt_reset;
  213. SB_GB clk_gbuf_I (
  214. .USER_SIGNAL_TO_GLOBAL_BUFFER(clk_in),
  215. .GLOBAL_BUFFER_OUTPUT(clk)
  216. );
  217. assign rst = ~cnt_reset[7];
  218. always @(posedge clk)
  219. if (cnt_reset[7] == 1'b0)
  220. cnt_reset <= cnt_reset + 1;
  221. endmodule // top