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