top.v 5.7 KB

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