usb_cdc_top.v 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. //-----------------------------------------------------------------
  2. // USB Serial Port
  3. // V0.1
  4. // Ultra-Embedded.com
  5. // Copyright 2020
  6. //
  7. // Email: admin@ultra-embedded.com
  8. //
  9. // License: LGPL
  10. //-----------------------------------------------------------------
  11. //
  12. // This source file may be used and distributed without
  13. // restriction provided that this copyright statement is not
  14. // removed from the file and that any derivative work contains
  15. // the original copyright notice and the associated disclaimer.
  16. //
  17. // This source file is free software; you can redistribute it
  18. // and/or modify it under the terms of the GNU Lesser General
  19. // Public License as published by the Free Software Foundation;
  20. // either version 2.1 of the License, or (at your option) any
  21. // later version.
  22. //
  23. // This source is distributed in the hope that it will be
  24. // useful, but WITHOUT ANY WARRANTY; without even the implied
  25. // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  26. // PURPOSE. See the GNU Lesser General Public License for more
  27. // details.
  28. //
  29. // You should have received a copy of the GNU Lesser General
  30. // Public License along with this source; if not, write to the
  31. // Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  32. // Boston, MA 02111-1307 USA
  33. //-----------------------------------------------------------------
  34. //-----------------------------------------------------------------
  35. // Generated File
  36. //-----------------------------------------------------------------
  37. module usb_cdc_top
  38. //-----------------------------------------------------------------
  39. // Params
  40. //-----------------------------------------------------------------
  41. #(
  42. parameter BAUDRATE = 115200
  43. )
  44. //-----------------------------------------------------------------
  45. // Ports
  46. //-----------------------------------------------------------------
  47. (
  48. input clk_i,
  49. input rst_i,
  50. output [7:0] utmi_data_out_o,
  51. output utmi_txvalid_o,
  52. output [1:0] utmi_op_mode_o,
  53. output [1:0] utmi_xcvrselect_o,
  54. output utmi_termselect_o,
  55. output utmi_dppulldown_o,
  56. output utmi_dmpulldown_o,
  57. input [7:0] utmi_data_in_i,
  58. input utmi_txready_i,
  59. input utmi_rxvalid_i,
  60. input utmi_rxactive_i,
  61. input utmi_rxerror_i,
  62. input [1:0] utmi_linestate_i,
  63. input tx_i,
  64. output rx_o,
  65. output rx_break_o
  66. );
  67. wire [ 7:0] usb_rx_data_w;
  68. wire usb_tx_accept_w;
  69. wire enable_w = 1'h1;
  70. wire usb_tx_valid_w;
  71. wire usb_rx_accept_w;
  72. wire [ 7:0] usb_tx_data_w;
  73. wire usb_rx_valid_w;
  74. wire usb_rx_break_w;
  75. usb_cdc_core
  76. u_usb
  77. (
  78. // Inputs
  79. .clk_i(clk_i)
  80. ,.rst_i(rst_i)
  81. ,.enable_i(enable_w)
  82. ,.utmi_data_in_i(utmi_data_in_i)
  83. ,.utmi_txready_i(utmi_txready_i)
  84. ,.utmi_rxvalid_i(utmi_rxvalid_i)
  85. ,.utmi_rxactive_i(utmi_rxactive_i)
  86. ,.utmi_rxerror_i(utmi_rxerror_i)
  87. ,.utmi_linestate_i(utmi_linestate_i)
  88. ,.inport_valid_i(usb_tx_valid_w)
  89. ,.inport_data_i(usb_tx_data_w)
  90. ,.outport_accept_i(usb_rx_accept_w)
  91. // Outputs
  92. ,.utmi_data_out_o(utmi_data_out_o)
  93. ,.utmi_txvalid_o(utmi_txvalid_o)
  94. ,.utmi_op_mode_o(utmi_op_mode_o)
  95. ,.utmi_xcvrselect_o(utmi_xcvrselect_o)
  96. ,.utmi_termselect_o(utmi_termselect_o)
  97. ,.utmi_dppulldown_o(utmi_dppulldown_o)
  98. ,.utmi_dmpulldown_o(utmi_dmpulldown_o)
  99. ,.inport_accept_o(usb_tx_accept_w)
  100. ,.outport_valid_o(usb_rx_valid_w)
  101. ,.outport_data_o(usb_rx_data_w)
  102. ,.outport_break_o(usb_rx_break_w)
  103. );
  104. //-----------------------------------------------------------------
  105. // Output FIFO
  106. //-----------------------------------------------------------------
  107. wire tx_valid_w;
  108. wire [7:0] tx_data_w;
  109. wire tx_accept_w;
  110. usb_cdc_fifo
  111. #(
  112. .WIDTH(8),
  113. .DEPTH(512),
  114. .ADDR_W(9)
  115. )
  116. u_fifo_tx
  117. (
  118. .clk_i(clk_i),
  119. .rst_i(rst_i),
  120. // In
  121. .push_i(tx_valid_w),
  122. .data_in_i(tx_data_w),
  123. .accept_o(tx_accept_w),
  124. // Out
  125. .pop_i(usb_tx_accept_w),
  126. .data_out_o(usb_tx_data_w),
  127. .valid_o(usb_tx_valid_w)
  128. );
  129. //-----------------------------------------------------------------
  130. // Input FIFO
  131. //-----------------------------------------------------------------
  132. wire rx_valid_w;
  133. wire [7:0] rx_data_w;
  134. wire rx_accept_w;
  135. usb_cdc_fifo
  136. #(
  137. .WIDTH(8),
  138. .DEPTH(512),
  139. .ADDR_W(9)
  140. )
  141. u_fifo_rx
  142. (
  143. .clk_i(clk_i),
  144. .rst_i(rst_i),
  145. // In
  146. .push_i(usb_rx_valid_w),
  147. .data_in_i(usb_rx_data_w),
  148. .accept_o(usb_rx_accept_w),
  149. // Out
  150. .pop_i(rx_accept_w),
  151. .data_out_o(rx_data_w),
  152. .valid_o(rx_valid_w)
  153. );
  154. //-----------------------------------------------------------------
  155. // Registers
  156. //-----------------------------------------------------------------
  157. // Configuration
  158. localparam STOP_BITS = 1'b0; // 0 = 1, 1 = 2
  159. localparam CLK_FREQ = 48000000;
  160. localparam BIT_DIV = (CLK_FREQ / BAUDRATE) - 1;
  161. localparam START_BIT = 4'd0;
  162. localparam STOP_BIT0 = 4'd9;
  163. localparam STOP_BIT1 = 4'd10;
  164. // Xilinx placement pragmas:
  165. //synthesis attribute IOB of txd_q is "TRUE"
  166. // TX Signals
  167. reg tx_busy_q;
  168. reg [3:0] tx_bits_q;
  169. reg [31:0] tx_count_q;
  170. reg [7:0] tx_shift_reg_q;
  171. reg txd_q;
  172. // RX Signals
  173. reg rxd_q;
  174. reg [7:0] rx_data_q;
  175. reg [3:0] rx_bits_q;
  176. reg [31:0] rx_count_q;
  177. reg [7:0] rx_shift_reg_q;
  178. reg rx_ready_q;
  179. reg rx_busy_q;
  180. reg rx_err_q;
  181. //-----------------------------------------------------------------
  182. // Re-sync RXD
  183. //-----------------------------------------------------------------
  184. reg rxd_ms_q;
  185. always @ (posedge clk_i or posedge rst_i)
  186. if (rst_i)
  187. begin
  188. rxd_ms_q <= 1'b1;
  189. rxd_q <= 1'b1;
  190. end
  191. else
  192. begin
  193. rxd_ms_q <= tx_i;
  194. rxd_q <= rxd_ms_q;
  195. end
  196. //-----------------------------------------------------------------
  197. // RX Clock Divider
  198. //-----------------------------------------------------------------
  199. wire rx_sample_w = (rx_count_q == 32'b0);
  200. always @ (posedge clk_i or posedge rst_i)
  201. if (rst_i)
  202. rx_count_q <= 32'b0;
  203. else
  204. begin
  205. // Inactive
  206. if (!rx_busy_q)
  207. rx_count_q <= {1'b0, BIT_DIV[31:1]};
  208. // Rx bit timer
  209. else if (rx_count_q != 0)
  210. rx_count_q <= (rx_count_q - 1);
  211. // Active
  212. else if (rx_sample_w)
  213. begin
  214. // Last bit?
  215. if ((rx_bits_q == STOP_BIT0 && !STOP_BITS) || (rx_bits_q == STOP_BIT1 && STOP_BITS))
  216. rx_count_q <= 32'b0;
  217. else
  218. rx_count_q <= BIT_DIV;
  219. end
  220. end
  221. //-----------------------------------------------------------------
  222. // RX Shift Register
  223. //-----------------------------------------------------------------
  224. always @ (posedge clk_i or posedge rst_i)
  225. if (rst_i)
  226. begin
  227. rx_shift_reg_q <= 8'h00;
  228. rx_busy_q <= 1'b0;
  229. end
  230. // Rx busy
  231. else if (rx_busy_q && rx_sample_w)
  232. begin
  233. // Last bit?
  234. if (rx_bits_q == STOP_BIT0 && !STOP_BITS)
  235. rx_busy_q <= 1'b0;
  236. else if (rx_bits_q == STOP_BIT1 && STOP_BITS)
  237. rx_busy_q <= 1'b0;
  238. else if (rx_bits_q == START_BIT)
  239. begin
  240. // Start bit should still be low as sampling mid
  241. // way through start bit, so if high, error!
  242. if (rxd_q)
  243. rx_busy_q <= 1'b0;
  244. end
  245. // Rx shift register
  246. else
  247. rx_shift_reg_q <= {rxd_q, rx_shift_reg_q[7:1]};
  248. end
  249. // Start bit?
  250. else if (!rx_busy_q && rxd_q == 1'b0)
  251. begin
  252. rx_shift_reg_q <= 8'h00;
  253. rx_busy_q <= 1'b1;
  254. end
  255. always @ (posedge clk_i or posedge rst_i)
  256. if (rst_i)
  257. rx_bits_q <= START_BIT;
  258. else if (rx_sample_w && rx_busy_q)
  259. begin
  260. if ((rx_bits_q == STOP_BIT1 && STOP_BITS) || (rx_bits_q == STOP_BIT0 && !STOP_BITS))
  261. rx_bits_q <= START_BIT;
  262. else
  263. rx_bits_q <= rx_bits_q + 4'd1;
  264. end
  265. else if (!rx_busy_q && (BIT_DIV == 32'b0))
  266. rx_bits_q <= START_BIT + 4'd1;
  267. else if (!rx_busy_q)
  268. rx_bits_q <= START_BIT;
  269. //-----------------------------------------------------------------
  270. // RX Data
  271. //-----------------------------------------------------------------
  272. always @ (posedge clk_i or posedge rst_i)
  273. if (rst_i)
  274. begin
  275. rx_ready_q <= 1'b0;
  276. rx_data_q <= 8'h00;
  277. rx_err_q <= 1'b0;
  278. end
  279. else
  280. begin
  281. // If reading data, reset data state
  282. if (tx_accept_w)
  283. begin
  284. rx_ready_q <= 1'b0;
  285. rx_err_q <= 1'b0;
  286. end
  287. if (rx_busy_q && rx_sample_w)
  288. begin
  289. // Stop bit
  290. if ((rx_bits_q == STOP_BIT1 && STOP_BITS) || (rx_bits_q == STOP_BIT0 && !STOP_BITS))
  291. begin
  292. // RXD should be still high
  293. if (rxd_q)
  294. begin
  295. rx_data_q <= rx_shift_reg_q;
  296. rx_ready_q <= 1'b1;
  297. end
  298. // Bad Stop bit - wait for a full bit period
  299. // before allowing start bit detection again
  300. else
  301. begin
  302. rx_ready_q <= 1'b0;
  303. rx_data_q <= 8'h00;
  304. rx_err_q <= 1'b1;
  305. end
  306. end
  307. // Mid start bit sample - if high then error
  308. else if (rx_bits_q == START_BIT && rxd_q)
  309. rx_err_q <= 1'b1;
  310. end
  311. end
  312. assign tx_data_w = rx_data_q;
  313. assign tx_valid_w = rx_ready_q;
  314. //-----------------------------------------------------------------
  315. // TX Clock Divider
  316. //-----------------------------------------------------------------
  317. wire tx_sample_w = (tx_count_q == 32'b0);
  318. always @ (posedge clk_i or posedge rst_i)
  319. if (rst_i)
  320. tx_count_q <= 32'b0;
  321. else
  322. begin
  323. // Idle
  324. if (!tx_busy_q)
  325. tx_count_q <= BIT_DIV;
  326. // Tx bit timer
  327. else if (tx_count_q != 0)
  328. tx_count_q <= (tx_count_q - 1);
  329. else if (tx_sample_w)
  330. tx_count_q <= BIT_DIV;
  331. end
  332. //-----------------------------------------------------------------
  333. // TX Shift Register
  334. //-----------------------------------------------------------------
  335. reg tx_complete_q;
  336. always @ (posedge clk_i or posedge rst_i)
  337. if (rst_i)
  338. begin
  339. tx_shift_reg_q <= 8'h00;
  340. tx_busy_q <= 1'b0;
  341. tx_complete_q <= 1'b0;
  342. end
  343. // Tx busy
  344. else if (tx_busy_q)
  345. begin
  346. // Shift tx data
  347. if (tx_bits_q != START_BIT && tx_sample_w)
  348. tx_shift_reg_q <= {1'b0, tx_shift_reg_q[7:1]};
  349. // Last bit?
  350. if (tx_bits_q == STOP_BIT0 && tx_sample_w && !STOP_BITS)
  351. begin
  352. tx_busy_q <= 1'b0;
  353. tx_complete_q <= 1'b1;
  354. end
  355. else if (tx_bits_q == STOP_BIT1 && tx_sample_w && STOP_BITS)
  356. begin
  357. tx_busy_q <= 1'b0;
  358. tx_complete_q <= 1'b1;
  359. end
  360. end
  361. // Buffer data to transmit
  362. else if (rx_valid_w)
  363. begin
  364. tx_shift_reg_q <= rx_data_w;
  365. tx_busy_q <= 1'b1;
  366. tx_complete_q <= 1'b0;
  367. end
  368. else
  369. tx_complete_q <= 1'b0;
  370. assign rx_accept_w = ~tx_busy_q;
  371. always @ (posedge clk_i or posedge rst_i)
  372. if (rst_i)
  373. tx_bits_q <= 4'd0;
  374. else if (tx_sample_w && tx_busy_q)
  375. begin
  376. if ((tx_bits_q == STOP_BIT1 && STOP_BITS) || (tx_bits_q == STOP_BIT0 && !STOP_BITS))
  377. tx_bits_q <= START_BIT;
  378. else
  379. tx_bits_q <= tx_bits_q + 4'd1;
  380. end
  381. //-----------------------------------------------------------------
  382. // UART Tx Pin
  383. //-----------------------------------------------------------------
  384. reg txd_r;
  385. always @ *
  386. begin
  387. txd_r = 1'b1;
  388. if (tx_busy_q)
  389. begin
  390. // Start bit (TXD = L)
  391. if (tx_bits_q == START_BIT)
  392. txd_r = 1'b0;
  393. // Stop bits (TXD = H)
  394. else if (tx_bits_q == STOP_BIT0 || tx_bits_q == STOP_BIT1)
  395. txd_r = 1'b1;
  396. // Data bits
  397. else
  398. txd_r = tx_shift_reg_q[0];
  399. end
  400. end
  401. always @ (posedge clk_i or posedge rst_i)
  402. if (rst_i)
  403. txd_q <= 1'b1;
  404. else
  405. txd_q <= txd_r;
  406. assign rx_o = txd_q;
  407. assign rx_break_o = usb_rx_break_w;
  408. endmodule
  409. module usb_cdc_fifo
  410. //-----------------------------------------------------------------
  411. // Params
  412. //-----------------------------------------------------------------
  413. #(
  414. parameter WIDTH = 8,
  415. parameter DEPTH = 4,
  416. parameter ADDR_W = 2
  417. )
  418. //-----------------------------------------------------------------
  419. // Ports
  420. //-----------------------------------------------------------------
  421. (
  422. // Inputs
  423. input clk_i
  424. ,input rst_i
  425. ,input [WIDTH-1:0] data_in_i
  426. ,input push_i
  427. ,input pop_i
  428. // Outputs
  429. ,output [WIDTH-1:0] data_out_o
  430. ,output accept_o
  431. ,output valid_o
  432. );
  433. //-----------------------------------------------------------------
  434. // Local Params
  435. //-----------------------------------------------------------------
  436. localparam COUNT_W = ADDR_W + 1;
  437. //-----------------------------------------------------------------
  438. // Registers
  439. //-----------------------------------------------------------------
  440. reg [WIDTH-1:0] ram_q[DEPTH-1:0];
  441. reg [ADDR_W-1:0] rd_ptr_q;
  442. reg [ADDR_W-1:0] wr_ptr_q;
  443. reg [COUNT_W-1:0] count_q;
  444. //-----------------------------------------------------------------
  445. // Sequential
  446. //-----------------------------------------------------------------
  447. always @ (posedge clk_i )
  448. if (rst_i)
  449. begin
  450. count_q <= {(COUNT_W) {1'b0}};
  451. rd_ptr_q <= {(ADDR_W) {1'b0}};
  452. wr_ptr_q <= {(ADDR_W) {1'b0}};
  453. end
  454. else
  455. begin
  456. // Push
  457. if (push_i & accept_o)
  458. begin
  459. ram_q[wr_ptr_q] <= data_in_i;
  460. wr_ptr_q <= wr_ptr_q + 1;
  461. end
  462. // Pop
  463. if (pop_i & valid_o)
  464. rd_ptr_q <= rd_ptr_q + 1;
  465. // Count up
  466. if ((push_i & accept_o) & ~(pop_i & valid_o))
  467. count_q <= count_q + 1;
  468. // Count down
  469. else if (~(push_i & accept_o) & (pop_i & valid_o))
  470. count_q <= count_q - 1;
  471. end
  472. //-------------------------------------------------------------------
  473. // Combinatorial
  474. //-------------------------------------------------------------------
  475. /* verilator lint_off WIDTH */
  476. assign valid_o = (count_q != 0);
  477. assign accept_o = (count_q != DEPTH);
  478. /* verilator lint_on WIDTH */
  479. assign data_out_o = ram_q[rd_ptr_q];
  480. endmodule