uart_mod.v 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. // vim: ts=4 sw=4 noexpandtab
  2. /*
  3. * UART
  4. *
  5. * Copyright (c) 2019 Michael Buesch <m@bues.ch>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. */
  21. `ifndef UART_MOD_V_
  22. `define UART_MOD_V_
  23. `include "sync_signal_mod.v"
  24. `include "edge_detect_mod.v"
  25. `ifndef UART_DEFAULT_DATABITS
  26. `define UART_DEFAULT_DATABITS 8
  27. `endif
  28. `ifndef UART_DEFAULT_PARITY_EVEN
  29. `define UART_DEFAULT_PARITY_EVEN 0
  30. `endif
  31. `ifndef UART_DEFAULT_STOP
  32. `define UART_DEFAULT_STOP 2
  33. `endif
  34. `ifndef UART_DEFAULT_ACTIVE_LOW
  35. `define UART_DEFAULT_ACTIVE_LOW 0
  36. `endif
  37. /* UART symbol clock generator */
  38. module uart_symclk (
  39. input clk, /* Clock */
  40. input n_reset, /* Not reset */
  41. input [23:0] clks_per_sym, /* Number of clocks per UART symbol */
  42. output reg setup, /* Setup edge (leading) */
  43. output reg sample, /* Setup point (center) */
  44. output reg symend, /* End edge (trailing) */
  45. );
  46. localparam CLKS_PER_SYM_MIN = 4; /* lower limit for clks_per_sym */
  47. reg [23:0] count;
  48. wire [23:0] clks_per_sym_limited;
  49. wire [23:0] clks_per_sym_half;
  50. assign clks_per_sym_limited = (clks_per_sym >= CLKS_PER_SYM_MIN) ? clks_per_sym : CLKS_PER_SYM_MIN;
  51. assign clks_per_sym_half = clks_per_sym_limited >> 1;
  52. initial begin
  53. count <= 0;
  54. setup <= 0;
  55. sample <= 0;
  56. symend <= 0;
  57. end
  58. always @(posedge clk) begin
  59. if (n_reset) begin
  60. if (count == 0) begin
  61. count <= count + 1;
  62. setup <= 1;
  63. sample <= 0;
  64. symend <= 0;
  65. end else if (count == clks_per_sym_half - 1) begin
  66. count <= count + 1;
  67. setup <= 0;
  68. sample <= 1;
  69. symend <= 0;
  70. end else if (count >= clks_per_sym_limited - 1) begin
  71. count <= 0;
  72. setup <= 0;
  73. sample <= 0;
  74. symend <= 1;
  75. end else begin
  76. count <= count + 1;
  77. setup <= 0;
  78. sample <= 0;
  79. symend <= 0;
  80. end
  81. end else begin
  82. count <= 0;
  83. setup <= 0;
  84. sample <= 0;
  85. symend <= 0;
  86. end
  87. end
  88. endmodule
  89. /* UART receiver */
  90. module uart_rx #(
  91. parameter DATABITS = `UART_DEFAULT_DATABITS,
  92. parameter PARITY_EVEN = `UART_DEFAULT_PARITY_EVEN,
  93. parameter ACTIVE_LOW = `UART_DEFAULT_ACTIVE_LOW,
  94. ) (
  95. input clk, /* Clock */
  96. input n_reset, /* Not reset */
  97. input [23:0] clks_per_sym, /* Number of clocks per UART symbol */
  98. input rx, /* Synchronized(!) receive signal line */
  99. output reg rx_irq, /* Data received interrupt */
  100. output reg rx_active, /* Receive in progress */
  101. output reg [DATABITS - 1 : 0] rx_data, /* Received data */
  102. output reg rx_parity, /* Received parity bit */
  103. output reg rx_parity_ok, /* Received parity Ok? */
  104. output reg rx_frame_error, /* Received frame had an error? */
  105. );
  106. `include "parity_func.v"
  107. localparam COUNT_START_WAIT = 0;
  108. localparam COUNT_START = COUNT_START_WAIT + 1;
  109. localparam COUNT_BIT0 = COUNT_START + 1;
  110. localparam COUNT_BIT1 = COUNT_BIT0 + ((DATABITS >= 2) ? 1 : 0);
  111. localparam COUNT_BIT2 = COUNT_BIT1 + ((DATABITS >= 3) ? 1 : 0);
  112. localparam COUNT_BIT3 = COUNT_BIT2 + ((DATABITS >= 4) ? 1 : 0);
  113. localparam COUNT_BIT4 = COUNT_BIT3 + ((DATABITS >= 5) ? 1 : 0);
  114. localparam COUNT_BIT5 = COUNT_BIT4 + ((DATABITS >= 6) ? 1 : 0);
  115. localparam COUNT_BIT6 = COUNT_BIT5 + ((DATABITS >= 7) ? 1 : 0);
  116. localparam COUNT_BIT7 = COUNT_BIT6 + ((DATABITS >= 8) ? 1 : 0);
  117. localparam COUNT_BIT8 = COUNT_BIT7 + ((DATABITS >= 9) ? 1 : 0);
  118. localparam COUNT_PARITY = COUNT_BIT8 + 1;
  119. localparam COUNT_STOP0 = COUNT_PARITY + 1;
  120. /* Receive signal. */
  121. wire rx_sig;
  122. wire rx_start;
  123. wire rx_falling;
  124. assign rx_sig = ACTIVE_LOW ? ~rx : rx;
  125. edge_detect rx_edge(.clk(clk), .signal(rx_sig), .falling(rx_falling));
  126. /* State machine */
  127. reg [3:0] sym_count;
  128. reg [DATABITS - 1 : 0] rx_buf;
  129. reg rx_parity_buf;
  130. reg rx_frame_error_start;
  131. /* Symbol clock */
  132. reg symclk_n_reset;
  133. wire symclk_sample;
  134. wire symclk_end;
  135. uart_symclk symclk (
  136. .clk(clk),
  137. .n_reset(symclk_n_reset),
  138. .clks_per_sym(clks_per_sym),
  139. .sample(symclk_sample),
  140. .symend(symclk_end),
  141. );
  142. /* Parity calculation */
  143. wire calc_rx_parity;
  144. assign calc_rx_parity = parity9(PARITY_EVEN ? EVEN : ODD,
  145. (DATABITS >= 1) ? rx_buf[0] : 0,
  146. (DATABITS >= 2) ? rx_buf[1] : 0,
  147. (DATABITS >= 3) ? rx_buf[2] : 0,
  148. (DATABITS >= 4) ? rx_buf[3] : 0,
  149. (DATABITS >= 5) ? rx_buf[4] : 0,
  150. (DATABITS >= 6) ? rx_buf[5] : 0,
  151. (DATABITS >= 7) ? rx_buf[6] : 0,
  152. (DATABITS >= 8) ? rx_buf[7] : 0,
  153. (DATABITS >= 9) ? rx_buf[8] : 0);
  154. initial begin
  155. rx_irq <= 0;
  156. rx_active <= 0;
  157. rx_data <= 0;
  158. rx_parity <= 0;
  159. rx_parity_ok <= 0;
  160. rx_frame_error <= 0;
  161. symclk_n_reset <= 0;
  162. sym_count <= COUNT_START_WAIT;
  163. rx_buf <= 0;
  164. rx_parity_buf <= 0;
  165. rx_frame_error_start <= 0;
  166. end
  167. always @(posedge clk) begin
  168. if (n_reset) begin
  169. if (sym_count == COUNT_START_WAIT) begin /* Waiting for start edge */
  170. if (rx_falling) begin
  171. symclk_n_reset <= 1;
  172. sym_count <= sym_count + 1;
  173. rx_buf <= 0;
  174. rx_active <= 1;
  175. end
  176. rx_irq <= 0;
  177. end else if (sym_count == COUNT_START) begin /* Start bit */
  178. if (symclk_sample) begin
  179. rx_frame_error_start <= rx_sig;
  180. end else if (symclk_end) begin
  181. sym_count <= sym_count + 1;
  182. end
  183. end else if ((sym_count == COUNT_BIT0) || /* Bit 0 */
  184. (sym_count == COUNT_BIT1) || /* Bit 1 */
  185. (sym_count == COUNT_BIT2) || /* Bit 2 */
  186. (sym_count == COUNT_BIT3) || /* Bit 3 */
  187. (sym_count == COUNT_BIT4) || /* Bit 4 */
  188. (sym_count == COUNT_BIT5) || /* Bit 5 */
  189. (sym_count == COUNT_BIT6) || /* Bit 6 */
  190. (sym_count == COUNT_BIT7) || /* Bit 7 */
  191. (sym_count == COUNT_BIT8)) begin /* Bit 8 */
  192. if (symclk_sample) begin
  193. rx_buf[sym_count - COUNT_BIT0] = rx_sig;
  194. end else if (symclk_end) begin
  195. sym_count <= sym_count + 1;
  196. end
  197. end else if (sym_count == COUNT_PARITY) begin /* Parity */
  198. if (symclk_sample) begin
  199. rx_parity_buf = rx_sig;
  200. end else if (symclk_end) begin
  201. sym_count <= sym_count + 1;
  202. end
  203. end else if (sym_count == COUNT_STOP0) begin /* Stop 0 */
  204. if (symclk_sample) begin
  205. rx_data <= rx_buf;
  206. rx_parity <= calc_rx_parity;
  207. rx_parity_ok <= (calc_rx_parity == rx_parity_buf);
  208. rx_frame_error <= rx_frame_error_start | ~rx_sig;
  209. rx_irq <= 1;
  210. rx_active <= 0;
  211. sym_count <= COUNT_START_WAIT;
  212. symclk_n_reset <= 0;
  213. end
  214. end else begin
  215. symclk_n_reset <= 0;
  216. sym_count <= COUNT_START_WAIT;
  217. rx_irq <= 0;
  218. rx_active <= 0;
  219. end
  220. end else begin
  221. symclk_n_reset <= 0;
  222. sym_count <= COUNT_START_WAIT;
  223. rx_irq <= 0;
  224. rx_active <= 0;
  225. end
  226. end
  227. endmodule
  228. /* UART transmitter */
  229. module uart_tx #(
  230. parameter DATABITS = `UART_DEFAULT_DATABITS,
  231. parameter PARITY_EVEN = `UART_DEFAULT_PARITY_EVEN,
  232. parameter STOP = `UART_DEFAULT_STOP,
  233. parameter ACTIVE_LOW = `UART_DEFAULT_ACTIVE_LOW,
  234. ) (
  235. input clk, /* Clock */
  236. input n_reset, /* Not reset */
  237. input [23:0] clks_per_sym, /* Number of clocks per UART symbol */
  238. output tx, /* Raw transmit signal line */
  239. output reg tx_irq, /* Data transmitted interrupt */
  240. output reg tx_active, /* Transmit in progress */
  241. input [DATABITS - 1 : 0] tx_data, /* Transmit data */
  242. input tx_trigger, /* Start transmission (only if not tx_active). */
  243. );
  244. `include "parity_func.v"
  245. localparam COUNT_START_WAIT = 0;
  246. localparam COUNT_START = COUNT_START_WAIT + 1;
  247. localparam COUNT_BIT0 = COUNT_START + 1;
  248. localparam COUNT_BIT1 = COUNT_BIT0 + ((DATABITS >= 2) ? 1 : 0);
  249. localparam COUNT_BIT2 = COUNT_BIT1 + ((DATABITS >= 3) ? 1 : 0);
  250. localparam COUNT_BIT3 = COUNT_BIT2 + ((DATABITS >= 4) ? 1 : 0);
  251. localparam COUNT_BIT4 = COUNT_BIT3 + ((DATABITS >= 5) ? 1 : 0);
  252. localparam COUNT_BIT5 = COUNT_BIT4 + ((DATABITS >= 6) ? 1 : 0);
  253. localparam COUNT_BIT6 = COUNT_BIT5 + ((DATABITS >= 7) ? 1 : 0);
  254. localparam COUNT_BIT7 = COUNT_BIT6 + ((DATABITS >= 8) ? 1 : 0);
  255. localparam COUNT_BIT8 = COUNT_BIT7 + ((DATABITS >= 9) ? 1 : 0);
  256. localparam COUNT_PARITY = COUNT_BIT8 + 1;
  257. localparam COUNT_STOP0 = COUNT_PARITY + 1;
  258. localparam COUNT_STOP1 = COUNT_STOP0 + ((STOP >= 2) ? 1 : 0);
  259. /* Output buffer. */
  260. reg tx_r;
  261. assign tx = ACTIVE_LOW ? ~tx_r : tx_r;
  262. /* State machine */
  263. reg [3:0] sym_count;
  264. reg [DATABITS - 1 : 0] tx_buf;
  265. /* Symbol clock */
  266. reg symclk_n_reset;
  267. wire symclk_setup;
  268. wire symclk_sample;
  269. wire symclk_end;
  270. uart_symclk symclk (
  271. .clk(clk),
  272. .n_reset(symclk_n_reset),
  273. .clks_per_sym(clks_per_sym),
  274. .setup(symclk_setup),
  275. .sample(symclk_sample),
  276. .symend(symclk_end),
  277. );
  278. /* Parity calculation */
  279. wire calc_tx_parity;
  280. assign calc_tx_parity = parity9(PARITY_EVEN ? EVEN : ODD,
  281. (DATABITS >= 1) ? tx_buf[0] : 0,
  282. (DATABITS >= 2) ? tx_buf[1] : 0,
  283. (DATABITS >= 3) ? tx_buf[2] : 0,
  284. (DATABITS >= 4) ? tx_buf[3] : 0,
  285. (DATABITS >= 5) ? tx_buf[4] : 0,
  286. (DATABITS >= 6) ? tx_buf[5] : 0,
  287. (DATABITS >= 7) ? tx_buf[6] : 0,
  288. (DATABITS >= 8) ? tx_buf[7] : 0,
  289. (DATABITS >= 9) ? tx_buf[8] : 0);
  290. initial begin
  291. tx_r <= 1;
  292. tx_irq <= 0;
  293. tx_active <= 0;
  294. symclk_n_reset <= 0;
  295. end
  296. always @(posedge clk) begin
  297. if (n_reset) begin
  298. if (sym_count == COUNT_START_WAIT) begin
  299. if (tx_trigger) begin
  300. symclk_n_reset <= 1;
  301. sym_count <= sym_count + 1;
  302. tx_buf <= tx_data;
  303. tx_active <= 1;
  304. end
  305. tx_r <= 1;
  306. tx_irq <= 0;
  307. end else if (sym_count == COUNT_START) begin /* Start bit */
  308. if (symclk_end) begin
  309. sym_count <= sym_count + 1;
  310. end
  311. tx_r <= 0;
  312. end else if ((sym_count == COUNT_BIT0) || /* Bit 0 */
  313. (sym_count == COUNT_BIT1) || /* Bit 1 */
  314. (sym_count == COUNT_BIT2) || /* Bit 2 */
  315. (sym_count == COUNT_BIT3) || /* Bit 3 */
  316. (sym_count == COUNT_BIT4) || /* Bit 4 */
  317. (sym_count == COUNT_BIT5) || /* Bit 5 */
  318. (sym_count == COUNT_BIT6) || /* Bit 6 */
  319. (sym_count == COUNT_BIT7) || /* Bit 7 */
  320. (sym_count == COUNT_BIT8)) begin /* Bit 8 */
  321. if (symclk_setup) begin
  322. tx_r <= tx_buf[sym_count - COUNT_BIT0];
  323. end else if (symclk_end) begin
  324. sym_count <= sym_count + 1;
  325. end
  326. end else if (sym_count == COUNT_PARITY) begin /* Parity */
  327. if (symclk_setup) begin
  328. tx_r <= calc_tx_parity;
  329. end else if (symclk_end) begin
  330. sym_count <= sym_count + 1;
  331. end
  332. end else if (sym_count == COUNT_STOP0 && STOP >= 1) begin /* Stop 0 */
  333. if (symclk_setup) begin
  334. tx_r <= 1;
  335. end else if (symclk_end) begin
  336. if (STOP >= 2) begin
  337. sym_count <= sym_count + 1;
  338. end else begin
  339. symclk_n_reset <= 0;
  340. sym_count <= COUNT_START_WAIT;
  341. tx_irq <= 1;
  342. tx_active <= 0;
  343. end
  344. end
  345. end else if (sym_count == COUNT_STOP1 && STOP >= 2) begin /* Stop 1 */
  346. if (symclk_setup) begin
  347. tx_r <= 1;
  348. end else if (symclk_end) begin
  349. symclk_n_reset <= 0;
  350. sym_count <= COUNT_START_WAIT;
  351. tx_irq <= 1;
  352. tx_active <= 0;
  353. end
  354. end else begin
  355. symclk_n_reset <= 0;
  356. sym_count <= COUNT_START_WAIT;
  357. tx_r <= 1;
  358. tx_irq <= 0;
  359. tx_active <= 0;
  360. end
  361. end else begin
  362. symclk_n_reset <= 0;
  363. sym_count <= COUNT_START_WAIT;
  364. tx_r <= 1;
  365. tx_irq <= 0;
  366. tx_active <= 0;
  367. end
  368. end
  369. endmodule
  370. /* UART full duplex transceiver */
  371. module uart_full_duplex #(
  372. parameter DATABITS = `UART_DEFAULT_DATABITS,
  373. parameter PARITY_EVEN = `UART_DEFAULT_PARITY_EVEN,
  374. parameter STOP = `UART_DEFAULT_STOP,
  375. parameter ACTIVE_LOW = `UART_DEFAULT_ACTIVE_LOW,
  376. ) (
  377. input clk, /* Clock */
  378. input n_reset, /* Not reset */
  379. input [23:0] clks_per_sym, /* Number of clocks per UART symbol */
  380. input rx, /* Raw receive signal line */
  381. output rx_irq, /* Data received interrupt */
  382. output rx_active, /* Receive in progress */
  383. output [DATABITS - 1 : 0] rx_data, /* Received data */
  384. output rx_parity, /* Received parity bit */
  385. output rx_parity_ok, /* Received parity Ok? */
  386. output rx_frame_error, /* Received frame had an error? */
  387. output tx, /* Raw transmit signal line */
  388. output tx_irq, /* Data transmitted interrupt */
  389. output tx_active, /* Transmit in progress */
  390. input [DATABITS - 1 : 0] tx_data, /* Transmit data */
  391. input tx_trigger, /* Start transmission (only if not tx_active). */
  392. );
  393. /* Synchronized receive signal. */
  394. wire rx_s;
  395. sync_signal sync_rx(.clk(clk), .in(rx), .out(rx_s));
  396. uart_rx #(
  397. .DATABITS(DATABITS),
  398. .PARITY_EVEN(PARITY_EVEN),
  399. .ACTIVE_LOW(ACTIVE_LOW),
  400. ) rx_mod (
  401. .clk(clk),
  402. .n_reset(n_reset),
  403. .clks_per_sym(clks_per_sym),
  404. .rx(rx_s),
  405. .rx_irq(rx_irq),
  406. .rx_active(rx_active),
  407. .rx_data(rx_data),
  408. .rx_parity(rx_parity),
  409. .rx_parity_ok(rx_parity_ok),
  410. .rx_frame_error(rx_frame_error),
  411. );
  412. uart_tx #(
  413. .DATABITS(DATABITS),
  414. .PARITY_EVEN(PARITY_EVEN),
  415. .STOP(STOP),
  416. .ACTIVE_LOW(ACTIVE_LOW),
  417. ) tx_mod (
  418. .clk(clk),
  419. .n_reset(n_reset),
  420. .clks_per_sym(clks_per_sym),
  421. .tx(tx),
  422. .tx_irq(tx_irq),
  423. .tx_active(tx_active),
  424. .tx_data(tx_data),
  425. .tx_trigger(tx_trigger),
  426. );
  427. endmodule
  428. /* UART half duplex bus arbiter */
  429. module uart_arbiter #(
  430. parameter ACTIVE_LOW = `UART_DEFAULT_ACTIVE_LOW,
  431. ) (
  432. input clk, /* Clock */
  433. input rx, /* Receive signal line */
  434. input tx_active, /* Transmit in progress */
  435. output tx_allowed, /* Transmit allowed now? */
  436. input rx_active, /* Receive in progress */
  437. output rx_allowed, /* Receive allowed now? */
  438. );
  439. wire rx_sig;
  440. assign rx_sig = ACTIVE_LOW ? ~rx : rx;
  441. /* Allow TX if:
  442. * - No RX is currently active AND
  443. * - The RX line is idle */
  444. assign tx_allowed = ~rx_active & rx_sig;
  445. /* Allow RX, if TX is currenly not active. */
  446. assign rx_allowed = ~tx_active;
  447. endmodule
  448. /* UART half duplex transceiver */
  449. module uart_half_duplex #(
  450. parameter DATABITS = `UART_DEFAULT_DATABITS,
  451. parameter PARITY_EVEN = `UART_DEFAULT_PARITY_EVEN,
  452. parameter STOP = `UART_DEFAULT_STOP,
  453. parameter ACTIVE_LOW = `UART_DEFAULT_ACTIVE_LOW,
  454. ) (
  455. input clk, /* Clock */
  456. input n_reset, /* Not reset */
  457. input [23:0] clks_per_sym, /* Number of clocks per UART symbol */
  458. input rx, /* Raw receive signal line */
  459. output rx_irq, /* Data received interrupt */
  460. output rx_active, /* Receive in progress */
  461. output [DATABITS - 1 : 0] rx_data, /* Received data */
  462. output rx_parity, /* Received parity bit */
  463. output rx_parity_ok, /* Received parity Ok? */
  464. output rx_frame_error, /* Received frame had an error? */
  465. output tx, /* Raw transmit signal line */
  466. output tx_irq, /* Data transmitted interrupt */
  467. output tx_active, /* Transmit in progress */
  468. output tx_pending, /* Start of transmission requested, but currenly blocked. */
  469. input [DATABITS - 1 : 0] tx_data, /* Transmit data */
  470. input tx_trigger, /* Start transmission (only if not tx_active). */
  471. );
  472. /* Synchronized receive signal. */
  473. wire rx_s;
  474. sync_signal sync_rx(.clk(clk), .in(rx), .out(rx_s));
  475. wire arb_tx_allowed;
  476. wire arb_rx_active;
  477. wire arb_rx_allowed;
  478. uart_arbiter #(
  479. .ACTIVE_LOW(ACTIVE_LOW),
  480. ) arb_mod (
  481. .clk(clk),
  482. .rx(rx_s),
  483. .tx_active(tx_active_w),
  484. .tx_allowed(arb_tx_allowed),
  485. .rx_active(arb_rx_active),
  486. .rx_allowed(arb_rx_allowed),
  487. );
  488. wire rx_n_reset;
  489. assign rx_n_reset = n_reset & arb_rx_allowed;
  490. assign rx_active = arb_rx_active;
  491. uart_rx #(
  492. .DATABITS(DATABITS),
  493. .PARITY_EVEN(PARITY_EVEN),
  494. .ACTIVE_LOW(ACTIVE_LOW),
  495. ) rx_mod (
  496. .clk(clk),
  497. .n_reset(rx_n_reset),
  498. .clks_per_sym(clks_per_sym),
  499. .rx(rx_s),
  500. .rx_irq(rx_irq),
  501. .rx_active(arb_rx_active),
  502. .rx_data(rx_data),
  503. .rx_parity(rx_parity),
  504. .rx_parity_ok(rx_parity_ok),
  505. .rx_frame_error(rx_frame_error),
  506. );
  507. reg tx_trigger_req;
  508. reg [DATABITS - 1 : 0] tx_data_r;
  509. wire tx_n_reset;
  510. wire tx_active_w;
  511. assign tx_n_reset = n_reset & (arb_tx_allowed | tx_active_w);
  512. assign tx_pending = tx_trigger_req;
  513. assign tx_active = tx_active_w;
  514. uart_tx #(
  515. .DATABITS(DATABITS),
  516. .PARITY_EVEN(PARITY_EVEN),
  517. .STOP(STOP),
  518. .ACTIVE_LOW(ACTIVE_LOW),
  519. ) tx_mod (
  520. .clk(clk),
  521. .n_reset(tx_n_reset),
  522. .clks_per_sym(clks_per_sym),
  523. .tx(tx),
  524. .tx_irq(tx_irq),
  525. .tx_active(tx_active_w),
  526. .tx_data(tx_data_r),
  527. .tx_trigger(tx_trigger_req),
  528. );
  529. initial begin
  530. tx_trigger_req <= 0;
  531. tx_data_r <= 0;
  532. end
  533. always @(posedge clk) begin
  534. if (n_reset) begin
  535. if (tx_trigger_req) begin
  536. if (arb_tx_allowed & ~tx_active_w & tx_n_reset) begin
  537. tx_trigger_req <= 0;
  538. tx_data_r <= 0;
  539. end
  540. end else begin
  541. /* If TX has been requested, store the request
  542. * so that it can be serviced after a possibly running
  543. * RX or TX transmission has finished. */
  544. if (tx_trigger) begin
  545. tx_trigger_req <= 1;
  546. tx_data_r <= tx_data;
  547. end
  548. end
  549. end else begin
  550. tx_trigger_req <= 0;
  551. tx_data_r <= 0;
  552. end
  553. end
  554. endmodule
  555. `endif /* UART_MOD_V_ */