usb_cdc_top.v 14 KB

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