top.v 6.0 KB

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