top.v 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * top.v
  3. *
  4. * Copyright (C) 2019 Sylvain Munaut <tnt@246tNt.com>
  5. * All rights reserved.
  6. *
  7. * BSD 3-clause, see LICENSE.bsd
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions are met:
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * * Neither the name of the <organization> nor the
  17. * names of its contributors may be used to endorse or promote products
  18. * derived from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23. * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  24. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  25. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  27. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. * vim: ts=4 sw=4
  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_BOOT = 3;
  55. // Signals
  56. // -------
  57. // Button input
  58. wire btn_iob;
  59. wire btn_v;
  60. wire btn_r;
  61. wire btn_f;
  62. // FSM
  63. reg [1:0] state_nxt;
  64. reg [1:0] state;
  65. // Boot selector
  66. wire boot_now;
  67. reg [1:0] boot_sel;
  68. // Timer/Counter
  69. reg [23:0] timer;
  70. wire timer_tick;
  71. wire timer_rst;
  72. // LED
  73. reg [3:0] dim;
  74. wire [2:0] rgb_pwm;
  75. // Clock / Reset
  76. wire clk;
  77. wire rst;
  78. // Button
  79. // ------
  80. SB_IO #(
  81. .PIN_TYPE(6'b000000),
  82. .PULLUP(1'b1),
  83. .IO_STANDARD("SB_LVCMOS")
  84. ) btn_iob_I (
  85. .PACKAGE_PIN(btn),
  86. .INPUT_CLK(clk),
  87. .D_IN_0(btn_iob)
  88. );
  89. glitch_filter #(
  90. .L(4),
  91. ) btn_flt_I (
  92. .pin_iob_reg(btn_iob),
  93. .cond(1'b1),
  94. .val(btn_v),
  95. .rise(btn_r),
  96. .fall(btn_f),
  97. .clk(clk),
  98. .rst(1'b0) // Ensure the glitch filter has settled
  99. // before logic here engages
  100. );
  101. // State machine
  102. // -------------
  103. // Next state logic
  104. always @(*)
  105. begin
  106. // Default is to stay put
  107. state_nxt <= state;
  108. // Main case
  109. case (state)
  110. ST_START:
  111. // Check for immediate boot
  112. state_nxt <= btn_v ? ST_BOOT : ST_WAIT;
  113. ST_WAIT:
  114. // Wait for first release
  115. if (btn_v == 1'b1)
  116. state_nxt <= ST_SEL;
  117. ST_SEL:
  118. // Wait for timeout
  119. if (timer_tick)
  120. state_nxt <= ST_BOOT;
  121. ST_BOOT:
  122. // Nothing to do ... will reconfigure shortly
  123. state_nxt <= state;
  124. endcase
  125. end
  126. // State register
  127. always @(posedge clk or posedge rst)
  128. if (rst)
  129. state <= ST_START;
  130. else
  131. state <= state_nxt;
  132. // Timer
  133. // -----
  134. always @(posedge clk)
  135. if (timer_rst)
  136. timer <= 24'h000000;
  137. else
  138. timer <= timer + 1;
  139. assign timer_rst = (btn_v == 1'b0) | timer_tick;
  140. assign timer_tick = timer[23];
  141. // Warm Boot
  142. // ---------
  143. // Boot command
  144. assign boot_now = (state == ST_BOOT);
  145. // Image select
  146. always @(posedge clk or posedge rst)
  147. begin
  148. if (rst)
  149. boot_sel <= 2'b10; // App 1 Image by default
  150. else if (state == ST_WAIT)
  151. boot_sel <= 2'b01; // DFU Image if in select mode
  152. else if (state == ST_SEL)
  153. boot_sel <= boot_sel + btn_f;
  154. end
  155. // IP
  156. SB_WARMBOOT warmboot (
  157. .BOOT(boot_now),
  158. .S0(boot_sel[0]),
  159. .S1(boot_sel[1])
  160. );
  161. // LED
  162. // ---
  163. assign rgb_pwm[0] = dim[3] & ~boot_now & boot_sel[0];
  164. assign rgb_pwm[1] = dim[3] & boot_now;
  165. assign rgb_pwm[2] = dim[3] & ~boot_now & boot_sel[1];
  166. assign ledr = ~boot_sel[0];
  167. assign ledg = ~boot_sel[1];
  168. // Dimming
  169. always @(posedge clk)
  170. if (rst)
  171. dim <= 4'h0;
  172. else
  173. dim <= dim[3] ? 4'h0 : (dim + 1);
  174. // Driver
  175. SB_RGBA_DRV #(
  176. .CURRENT_MODE("0b1"),
  177. .RGB0_CURRENT("0b000001"),
  178. .RGB1_CURRENT("0b000001"),
  179. .RGB2_CURRENT("0b000001")
  180. ) rgb_drv_I (
  181. .RGBLEDEN(1'b1),
  182. .RGB0PWM(rgb_pwm[0]),
  183. .RGB1PWM(rgb_pwm[1]),
  184. .RGB2PWM(rgb_pwm[2]),
  185. .CURREN(1'b1),
  186. .RGB0(rgb[0]),
  187. .RGB1(rgb[1]),
  188. .RGB2(rgb[2])
  189. );
  190. // Dummy USB
  191. // ---------
  192. // (to avoid pullups triggering detection)
  193. SB_IO #(
  194. .PIN_TYPE(6'b101000),
  195. .PULLUP(1'b0),
  196. .IO_STANDARD("SB_LVCMOS")
  197. ) usb[2:0] (
  198. .PACKAGE_PIN({usb_dp, usb_dn, usb_pu}),
  199. .OUTPUT_ENABLE(1'b0),
  200. .D_OUT_0(1'b0)
  201. );
  202. // Clock / Reset
  203. // -------------
  204. reg [7:0] cnt_reset;
  205. SB_GB clk_gbuf_I (
  206. .USER_SIGNAL_TO_GLOBAL_BUFFER(clk_in),
  207. .GLOBAL_BUFFER_OUTPUT(clk)
  208. );
  209. assign rst = ~cnt_reset[7];
  210. always @(posedge clk)
  211. if (cnt_reset[7] == 1'b0)
  212. cnt_reset <= cnt_reset + 1;
  213. endmodule // top