2
0

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. );
  66. wire [ 7:0] usb_rx_data_w;
  67. wire usb_tx_accept_w;
  68. wire enable_w = 1'h1;
  69. wire usb_tx_valid_w;
  70. wire usb_rx_accept_w;
  71. wire [ 7:0] usb_tx_data_w;
  72. wire usb_rx_valid_w;
  73. usb_cdc_core
  74. u_usb
  75. (
  76. // Inputs
  77. .clk_i(clk_i)
  78. ,.rst_i(rst_i)
  79. ,.enable_i(enable_w)
  80. ,.utmi_data_in_i(utmi_data_in_i)
  81. ,.utmi_txready_i(utmi_txready_i)
  82. ,.utmi_rxvalid_i(utmi_rxvalid_i)
  83. ,.utmi_rxactive_i(utmi_rxactive_i)
  84. ,.utmi_rxerror_i(utmi_rxerror_i)
  85. ,.utmi_linestate_i(utmi_linestate_i)
  86. ,.inport_valid_i(usb_tx_valid_w)
  87. ,.inport_data_i(usb_tx_data_w)
  88. ,.outport_accept_i(usb_rx_accept_w)
  89. // Outputs
  90. ,.utmi_data_out_o(utmi_data_out_o)
  91. ,.utmi_txvalid_o(utmi_txvalid_o)
  92. ,.utmi_op_mode_o(utmi_op_mode_o)
  93. ,.utmi_xcvrselect_o(utmi_xcvrselect_o)
  94. ,.utmi_termselect_o(utmi_termselect_o)
  95. ,.utmi_dppulldown_o(utmi_dppulldown_o)
  96. ,.utmi_dmpulldown_o(utmi_dmpulldown_o)
  97. ,.inport_accept_o(usb_tx_accept_w)
  98. ,.outport_valid_o(usb_rx_valid_w)
  99. ,.outport_data_o(usb_rx_data_w)
  100. );
  101. //-----------------------------------------------------------------
  102. // Output FIFO
  103. //-----------------------------------------------------------------
  104. wire tx_valid_w;
  105. wire [7:0] tx_data_w;
  106. wire tx_accept_w;
  107. usb_cdc_fifo
  108. #(
  109. .WIDTH(8),
  110. .DEPTH(512),
  111. .ADDR_W(9)
  112. )
  113. u_fifo_tx
  114. (
  115. .clk_i(clk_i),
  116. .rst_i(rst_i),
  117. // In
  118. .push_i(tx_valid_w),
  119. .data_in_i(tx_data_w),
  120. .accept_o(tx_accept_w),
  121. // Out
  122. .pop_i(usb_tx_accept_w),
  123. .data_out_o(usb_tx_data_w),
  124. .valid_o(usb_tx_valid_w)
  125. );
  126. //-----------------------------------------------------------------
  127. // Input FIFO
  128. //-----------------------------------------------------------------
  129. wire rx_valid_w;
  130. wire [7:0] rx_data_w;
  131. wire rx_accept_w;
  132. usb_cdc_fifo
  133. #(
  134. .WIDTH(8),
  135. .DEPTH(512),
  136. .ADDR_W(9)
  137. )
  138. u_fifo_rx
  139. (
  140. .clk_i(clk_i),
  141. .rst_i(rst_i),
  142. // In
  143. .push_i(usb_rx_valid_w),
  144. .data_in_i(usb_rx_data_w),
  145. .accept_o(usb_rx_accept_w),
  146. // Out
  147. .pop_i(rx_accept_w),
  148. .data_out_o(rx_data_w),
  149. .valid_o(rx_valid_w)
  150. );
  151. //-----------------------------------------------------------------
  152. // Registers
  153. //-----------------------------------------------------------------
  154. // Configuration
  155. localparam STOP_BITS = 1'b0; // 0 = 1, 1 = 2
  156. localparam CLK_FREQ = 48000000;
  157. localparam BIT_DIV = (CLK_FREQ / BAUDRATE) - 1;
  158. localparam START_BIT = 4'd0;
  159. localparam STOP_BIT0 = 4'd9;
  160. localparam STOP_BIT1 = 4'd10;
  161. // Xilinx placement pragmas:
  162. //synthesis attribute IOB of txd_q is "TRUE"
  163. // TX Signals
  164. reg tx_busy_q;
  165. reg [3:0] tx_bits_q;
  166. reg [31:0] tx_count_q;
  167. reg [7:0] tx_shift_reg_q;
  168. reg txd_q;
  169. // RX Signals
  170. reg rxd_q;
  171. reg [7:0] rx_data_q;
  172. reg [3:0] rx_bits_q;
  173. reg [31:0] rx_count_q;
  174. reg [7:0] rx_shift_reg_q;
  175. reg rx_ready_q;
  176. reg rx_busy_q;
  177. reg rx_err_q;
  178. //-----------------------------------------------------------------
  179. // Re-sync RXD
  180. //-----------------------------------------------------------------
  181. reg rxd_ms_q;
  182. always @ (posedge clk_i or posedge rst_i)
  183. if (rst_i)
  184. begin
  185. rxd_ms_q <= 1'b1;
  186. rxd_q <= 1'b1;
  187. end
  188. else
  189. begin
  190. rxd_ms_q <= tx_i;
  191. rxd_q <= rxd_ms_q;
  192. end
  193. //-----------------------------------------------------------------
  194. // RX Clock Divider
  195. //-----------------------------------------------------------------
  196. wire rx_sample_w = (rx_count_q == 32'b0);
  197. always @ (posedge clk_i or posedge rst_i)
  198. if (rst_i)
  199. rx_count_q <= 32'b0;
  200. else
  201. begin
  202. // Inactive
  203. if (!rx_busy_q)
  204. rx_count_q <= {1'b0, BIT_DIV[31:1]};
  205. // Rx bit timer
  206. else if (rx_count_q != 0)
  207. rx_count_q <= (rx_count_q - 1);
  208. // Active
  209. else if (rx_sample_w)
  210. begin
  211. // Last bit?
  212. if ((rx_bits_q == STOP_BIT0 && !STOP_BITS) || (rx_bits_q == STOP_BIT1 && STOP_BITS))
  213. rx_count_q <= 32'b0;
  214. else
  215. rx_count_q <= BIT_DIV;
  216. end
  217. end
  218. //-----------------------------------------------------------------
  219. // RX Shift Register
  220. //-----------------------------------------------------------------
  221. always @ (posedge clk_i or posedge rst_i)
  222. if (rst_i)
  223. begin
  224. rx_shift_reg_q <= 8'h00;
  225. rx_busy_q <= 1'b0;
  226. end
  227. // Rx busy
  228. else if (rx_busy_q && rx_sample_w)
  229. begin
  230. // Last bit?
  231. if (rx_bits_q == STOP_BIT0 && !STOP_BITS)
  232. rx_busy_q <= 1'b0;
  233. else if (rx_bits_q == STOP_BIT1 && STOP_BITS)
  234. rx_busy_q <= 1'b0;
  235. else if (rx_bits_q == START_BIT)
  236. begin
  237. // Start bit should still be low as sampling mid
  238. // way through start bit, so if high, error!
  239. if (rxd_q)
  240. rx_busy_q <= 1'b0;
  241. end
  242. // Rx shift register
  243. else
  244. rx_shift_reg_q <= {rxd_q, rx_shift_reg_q[7:1]};
  245. end
  246. // Start bit?
  247. else if (!rx_busy_q && rxd_q == 1'b0)
  248. begin
  249. rx_shift_reg_q <= 8'h00;
  250. rx_busy_q <= 1'b1;
  251. end
  252. always @ (posedge clk_i or posedge rst_i)
  253. if (rst_i)
  254. rx_bits_q <= START_BIT;
  255. else if (rx_sample_w && rx_busy_q)
  256. begin
  257. if ((rx_bits_q == STOP_BIT1 && STOP_BITS) || (rx_bits_q == STOP_BIT0 && !STOP_BITS))
  258. rx_bits_q <= START_BIT;
  259. else
  260. rx_bits_q <= rx_bits_q + 4'd1;
  261. end
  262. else if (!rx_busy_q && (BIT_DIV == 32'b0))
  263. rx_bits_q <= START_BIT + 4'd1;
  264. else if (!rx_busy_q)
  265. rx_bits_q <= START_BIT;
  266. //-----------------------------------------------------------------
  267. // RX Data
  268. //-----------------------------------------------------------------
  269. always @ (posedge clk_i or posedge rst_i)
  270. if (rst_i)
  271. begin
  272. rx_ready_q <= 1'b0;
  273. rx_data_q <= 8'h00;
  274. rx_err_q <= 1'b0;
  275. end
  276. else
  277. begin
  278. // If reading data, reset data state
  279. if (tx_accept_w)
  280. begin
  281. rx_ready_q <= 1'b0;
  282. rx_err_q <= 1'b0;
  283. end
  284. if (rx_busy_q && rx_sample_w)
  285. begin
  286. // Stop bit
  287. if ((rx_bits_q == STOP_BIT1 && STOP_BITS) || (rx_bits_q == STOP_BIT0 && !STOP_BITS))
  288. begin
  289. // RXD should be still high
  290. if (rxd_q)
  291. begin
  292. rx_data_q <= rx_shift_reg_q;
  293. rx_ready_q <= 1'b1;
  294. end
  295. // Bad Stop bit - wait for a full bit period
  296. // before allowing start bit detection again
  297. else
  298. begin
  299. rx_ready_q <= 1'b0;
  300. rx_data_q <= 8'h00;
  301. rx_err_q <= 1'b1;
  302. end
  303. end
  304. // Mid start bit sample - if high then error
  305. else if (rx_bits_q == START_BIT && rxd_q)
  306. rx_err_q <= 1'b1;
  307. end
  308. end
  309. assign tx_data_w = rx_data_q;
  310. assign tx_valid_w = rx_ready_q;
  311. //-----------------------------------------------------------------
  312. // TX Clock Divider
  313. //-----------------------------------------------------------------
  314. wire tx_sample_w = (tx_count_q == 32'b0);
  315. always @ (posedge clk_i or posedge rst_i)
  316. if (rst_i)
  317. tx_count_q <= 32'b0;
  318. else
  319. begin
  320. // Idle
  321. if (!tx_busy_q)
  322. tx_count_q <= BIT_DIV;
  323. // Tx bit timer
  324. else if (tx_count_q != 0)
  325. tx_count_q <= (tx_count_q - 1);
  326. else if (tx_sample_w)
  327. tx_count_q <= BIT_DIV;
  328. end
  329. //-----------------------------------------------------------------
  330. // TX Shift Register
  331. //-----------------------------------------------------------------
  332. reg tx_complete_q;
  333. always @ (posedge clk_i or posedge rst_i)
  334. if (rst_i)
  335. begin
  336. tx_shift_reg_q <= 8'h00;
  337. tx_busy_q <= 1'b0;
  338. tx_complete_q <= 1'b0;
  339. end
  340. // Tx busy
  341. else if (tx_busy_q)
  342. begin
  343. // Shift tx data
  344. if (tx_bits_q != START_BIT && tx_sample_w)
  345. tx_shift_reg_q <= {1'b0, tx_shift_reg_q[7:1]};
  346. // Last bit?
  347. if (tx_bits_q == STOP_BIT0 && tx_sample_w && !STOP_BITS)
  348. begin
  349. tx_busy_q <= 1'b0;
  350. tx_complete_q <= 1'b1;
  351. end
  352. else if (tx_bits_q == STOP_BIT1 && tx_sample_w && STOP_BITS)
  353. begin
  354. tx_busy_q <= 1'b0;
  355. tx_complete_q <= 1'b1;
  356. end
  357. end
  358. // Buffer data to transmit
  359. else if (rx_valid_w)
  360. begin
  361. tx_shift_reg_q <= rx_data_w;
  362. tx_busy_q <= 1'b1;
  363. tx_complete_q <= 1'b0;
  364. end
  365. else
  366. tx_complete_q <= 1'b0;
  367. assign rx_accept_w = ~tx_busy_q;
  368. always @ (posedge clk_i or posedge rst_i)
  369. if (rst_i)
  370. tx_bits_q <= 4'd0;
  371. else if (tx_sample_w && tx_busy_q)
  372. begin
  373. if ((tx_bits_q == STOP_BIT1 && STOP_BITS) || (tx_bits_q == STOP_BIT0 && !STOP_BITS))
  374. tx_bits_q <= START_BIT;
  375. else
  376. tx_bits_q <= tx_bits_q + 4'd1;
  377. end
  378. //-----------------------------------------------------------------
  379. // UART Tx Pin
  380. //-----------------------------------------------------------------
  381. reg txd_r;
  382. always @ *
  383. begin
  384. txd_r = 1'b1;
  385. if (tx_busy_q)
  386. begin
  387. // Start bit (TXD = L)
  388. if (tx_bits_q == START_BIT)
  389. txd_r = 1'b0;
  390. // Stop bits (TXD = H)
  391. else if (tx_bits_q == STOP_BIT0 || tx_bits_q == STOP_BIT1)
  392. txd_r = 1'b1;
  393. // Data bits
  394. else
  395. txd_r = tx_shift_reg_q[0];
  396. end
  397. end
  398. always @ (posedge clk_i or posedge rst_i)
  399. if (rst_i)
  400. txd_q <= 1'b1;
  401. else
  402. txd_q <= txd_r;
  403. assign rx_o = txd_q;
  404. endmodule
  405. module usb_cdc_fifo
  406. //-----------------------------------------------------------------
  407. // Params
  408. //-----------------------------------------------------------------
  409. #(
  410. parameter WIDTH = 8,
  411. parameter DEPTH = 4,
  412. parameter ADDR_W = 2
  413. )
  414. //-----------------------------------------------------------------
  415. // Ports
  416. //-----------------------------------------------------------------
  417. (
  418. // Inputs
  419. input clk_i
  420. ,input rst_i
  421. ,input [WIDTH-1:0] data_in_i
  422. ,input push_i
  423. ,input pop_i
  424. // Outputs
  425. ,output [WIDTH-1:0] data_out_o
  426. ,output accept_o
  427. ,output valid_o
  428. );
  429. //-----------------------------------------------------------------
  430. // Local Params
  431. //-----------------------------------------------------------------
  432. localparam COUNT_W = ADDR_W + 1;
  433. //-----------------------------------------------------------------
  434. // Registers
  435. //-----------------------------------------------------------------
  436. reg [WIDTH-1:0] ram_q[DEPTH-1:0];
  437. reg [ADDR_W-1:0] rd_ptr_q;
  438. reg [ADDR_W-1:0] wr_ptr_q;
  439. reg [COUNT_W-1:0] count_q;
  440. //-----------------------------------------------------------------
  441. // Sequential
  442. //-----------------------------------------------------------------
  443. always @ (posedge clk_i )
  444. if (rst_i)
  445. begin
  446. count_q <= {(COUNT_W) {1'b0}};
  447. rd_ptr_q <= {(ADDR_W) {1'b0}};
  448. wr_ptr_q <= {(ADDR_W) {1'b0}};
  449. end
  450. else
  451. begin
  452. // Push
  453. if (push_i & accept_o)
  454. begin
  455. ram_q[wr_ptr_q] <= data_in_i;
  456. wr_ptr_q <= wr_ptr_q + 1;
  457. end
  458. // Pop
  459. if (pop_i & valid_o)
  460. rd_ptr_q <= rd_ptr_q + 1;
  461. // Count up
  462. if ((push_i & accept_o) & ~(pop_i & valid_o))
  463. count_q <= count_q + 1;
  464. // Count down
  465. else if (~(push_i & accept_o) & (pop_i & valid_o))
  466. count_q <= count_q - 1;
  467. end
  468. //-------------------------------------------------------------------
  469. // Combinatorial
  470. //-------------------------------------------------------------------
  471. /* verilator lint_off WIDTH */
  472. assign valid_o = (count_q != 0);
  473. assign accept_o = (count_q != DEPTH);
  474. /* verilator lint_on WIDTH */
  475. assign data_out_o = ram_q[rd_ptr_q];
  476. endmodule