serial.sv 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //
  2. // Simple serial port.
  3. //
  4. // The transmission rate is fixed to 1 Mbps.
  5. //
  6. // If the output FIFO is full, an output signal is asserted, which
  7. // is expected to be used together with DTR to provide blocking I/O
  8. // if desired.
  9. //
  10. module serial
  11. #(
  12. parameter logic ENABLE_RX_DATA = 1'b1,
  13. parameter logic ENABLE_RX_BREAK = 1'b1,
  14. parameter logic ENABLE_TX_DATA = 1'b1,
  15. parameter logic ENABLE_TX_BREAK = 1'b1,
  16. parameter logic BAUDRATE_SETTABLE = 1'b0,
  17. parameter [31:0] BAUDRATE = 115200,
  18. parameter [31:0] TTY_CLK = 84000000,
  19. parameter NCO_BITS = 24,
  20. parameter BREAK_BITS = 16 // Bit times for BREAK detect
  21. )
  22. (
  23. input tri1 rst_n,
  24. input clk,
  25. output tty_tx,
  26. input tty_rx,
  27. input tx_wstrb,
  28. input [7:0] tx_data,
  29. input tx_break, // BREAK is asserted as long as this is true
  30. output tx_full,
  31. output tx_empty,
  32. input tri0 tx_flush,
  33. input rx_rstrb,
  34. output [7:0] rx_data,
  35. output rx_break,
  36. output rx_full,
  37. output rx_empty,
  38. input tri0 rx_flush,
  39. input [NCO_BITS-1:0] divisor, // If divisor is settable
  40. input tri0 divisor_wstrb
  41. );
  42. `include "functions.sv" // For ModelSim
  43. //
  44. // Baud rate generator; produces a clock enable synchronous
  45. // with clk. This is based on a numerically controlled oscillator
  46. // (NCO); the baudrate is given as a binary fraction of the input
  47. // clock rate divided by the oversampling rate (16); for practical
  48. // reasons represented minus one LSB so 0x0.ffffff -> 1
  49. // and 0 -> 0x0.000001.
  50. //
  51. // The term "divisor" here is probably misleading, since it is
  52. // actually a fixed-point *multiplier* which is <= 1.
  53. //
  54. localparam [NCO_BITS-1:0] default_divisor =
  55. round_div(BAUDRATE << NCO_BITS, TTY_CLK >> 4) - 1'b1;
  56. reg [NCO_BITS-1:0] divisor_q = default_divisor;
  57. reg [NCO_BITS-1:0] nco_q;
  58. reg tty_clk_en; // tty clock tick (clock enable)
  59. always @(posedge clk)
  60. { tty_clk_en, nco_q } <= nco_q + divisor_q + 1'b1;
  61. always @(negedge rst_n or posedge clk)
  62. if (~rst_n)
  63. divisor_q <= default_divisor;
  64. else if ( BAUDRATE_SETTABLE & divisor_wstrb )
  65. divisor_q <= divisor;
  66. //
  67. // **** Transmitter section ****
  68. //
  69. reg tx_rdack;
  70. wire [7:0] tx_out_data;
  71. //
  72. // FIFO
  73. //
  74. generate if (ENABLE_TX_DATA)
  75. begin
  76. //
  77. // Tx FIFO
  78. //
  79. reg tx_wstrb_q;
  80. always @(negedge rst_n or posedge clk)
  81. if (~rst_n)
  82. tx_wstrb_q <= 1'b0;
  83. else
  84. tx_wstrb_q <= tx_wstrb;
  85. fifo txfifo (
  86. .aclr ( ~rst_n ),
  87. .clock ( clk ),
  88. .data ( tx_data ),
  89. .wrreq ( tx_wstrb & ~tx_wstrb_q ),
  90. .sclr ( tx_flush ),
  91. .empty ( tx_empty ),
  92. .full ( tx_full ),
  93. .rdreq ( tx_rdack ),
  94. .q ( tx_out_data ),
  95. .usedw ( )
  96. );
  97. end // if (ENABLE_TX_DATA)
  98. else
  99. begin
  100. assign tx_empty = 1'b1;
  101. assign tx_full = 1'b1;
  102. assign tx_out_data = 8'hxx;
  103. end
  104. endgenerate
  105. //
  106. // Transmitter
  107. //
  108. generate if (ENABLE_TX_DATA | ENABLE_TX_BREAK)
  109. begin
  110. reg [3:0] tx_phase;
  111. reg [3:0] tx_ctr;
  112. reg [9:0] tx_sr = ~10'b0;
  113. reg tx_sending_break;
  114. always @(negedge rst_n or posedge clk)
  115. if (~rst_n)
  116. begin
  117. tx_phase <= 4'h0;
  118. tx_ctr <= 'd0;
  119. tx_sr <= 10'h3ff; // Line idle
  120. tx_rdack <= 1'b0;
  121. tty_tx <= 1'b1;
  122. tx_sending_break <= 1'b0;
  123. end
  124. else
  125. begin
  126. tx_rdack <= 1'b0;
  127. tty_tx <= tx_sr[0] & ~tx_sending_break;
  128. if ( tty_clk_en )
  129. begin
  130. tx_phase <= tx_phase + 1'b1;
  131. if (&tx_phase)
  132. begin
  133. tx_sr[8:0] <= tx_sr[9:1];
  134. tx_sr[9] <= 1'b1; // Stop bit/idle
  135. if (|tx_ctr)
  136. begin
  137. tx_ctr <= tx_ctr - 1'b1;
  138. end
  139. else if ( ENABLE_TX_BREAK &
  140. (tx_break | tx_sending_break) )
  141. begin
  142. // Make sure we get an idle bit after break
  143. tx_sending_break <= tx_break;
  144. end
  145. else if ( ~tx_empty )
  146. begin
  147. tx_sr[9:2] <= tx_out_data;
  148. tx_sr[1] <= 1'b0; // Start bit
  149. // 10 = start bit + data + stop bit
  150. tx_ctr <= 'd10;
  151. tx_rdack <= 1'b1; // Remove from FIFO
  152. end
  153. end // if (tx_phase == 4'hF)
  154. end // if ( tty_clk_en )
  155. end // else: !if(~rst_n)
  156. end // if (ENABLE_TX_DATA | ENABLE_TX_BREAK)
  157. else
  158. begin
  159. assign tty_tx = 1'b1;
  160. end // else: !if(ENABLE_TX_DATA | ENABLE_TX_BREAK)
  161. endgenerate
  162. //
  163. // **** Receiver section ****
  164. //
  165. //
  166. // Bit phase counter
  167. //
  168. generate if (ENABLE_RX_DATA | ENABLE_RX_BREAK)
  169. begin
  170. reg [3:0] rx_phase;
  171. reg rx_phase_start = 1'b0;
  172. always @(negedge rst_n or posedge clk)
  173. if (~rst_n)
  174. rx_phase <= 4'b0;
  175. else if ( rx_phase_start )
  176. rx_phase <= 4'h8; // Start bit flank detected
  177. else
  178. rx_phase <= rx_phase + tty_clk_en;
  179. end // if (ENABLE_RX_DATA | ENABLE_RX_BREAK)
  180. endgenerate
  181. //
  182. // BREAK detect
  183. //
  184. generate if (ENABLE_RX_BREAK)
  185. begin
  186. reg [BREAK_BITS-1:0] rx_break_ctr;
  187. wire [BREAK_BITS:0] rx_break_ctr_next = rx_break_ctr + 1'b1;
  188. always @(negedge rst_n or posedge clk)
  189. if (~rst_n)
  190. begin
  191. rx_break_ctr <= 'b0;
  192. rx_break <= 1'b0;
  193. end
  194. else
  195. begin
  196. if ( tty_clk_en )
  197. begin
  198. if ( tty_rx )
  199. begin
  200. // Rx high = not a break
  201. rx_break_ctr <= 'b0;
  202. rx_break <= 1'b0;
  203. end
  204. else if ( &rx_phase )
  205. begin
  206. rx_break_ctr <= rx_break_ctr_next;
  207. rx_break <= rx_break | rx_break_ctr_next[BREAK_BITS];
  208. end // else: !if(tty_rxd)
  209. end // if ( tty_clk_en )
  210. end // else: !if(~rst_n)
  211. end // if (ENABLE_RX_BREAK)
  212. else
  213. begin
  214. assign rx_break = 1'b0;
  215. end
  216. endgenerate
  217. //
  218. // Data receive
  219. //
  220. generate if (ENABLE_RX_DATA)
  221. begin
  222. reg rx_recv_strb;
  223. reg rx_rstrb_q;
  224. fifo rxfifo (
  225. .aclr ( ~rst_n ),
  226. .clock ( clk ),
  227. .rdreq ( ~rx_rstrb & rx_rstrb_q ), // Advance after read
  228. .q ( rx_data ),
  229. .sclr ( rx_flush ),
  230. .empty ( rx_empty ),
  231. .full ( rx_full ),
  232. .wrreq ( rx_recv_strb ),
  233. .data ( rx_sr ),
  234. .usedw ( )
  235. );
  236. reg [3:0] rx_ctr;
  237. reg [2:0] rx_bits;
  238. reg [7:0] rx_sr;
  239. reg tty_clk_en_q;
  240. always @(negedge rst_n or posedge clk)
  241. if (~rst_n)
  242. begin
  243. rx_ctr <= 4'b0;
  244. rx_bits <= 3'b111;
  245. rx_sr <= 8'hxx;
  246. tty_clk_en_q <= 1'b0;
  247. rx_rstrb_q <= 1'b0;
  248. rx_recv_strb <= 1'b0;
  249. rx_phase_start <= 1'b0;
  250. end
  251. else
  252. begin
  253. rx_rstrb_q <= rx_rstrb;
  254. tty_clk_en_q <= tty_clk_en;
  255. rx_recv_strb <= 1'b0;
  256. if ( tty_clk_en )
  257. rx_bits <= { rx_bits[1:0], tty_rx };
  258. if ( tty_clk_en_q )
  259. begin
  260. if ( !rx_ctr )
  261. begin
  262. if ( rx_bits == 3'b100 )
  263. begin
  264. rx_ctr <= 4'd10;
  265. rx_phase_start <= 1'b1;
  266. end
  267. end
  268. else if ( !rx_phase )
  269. begin
  270. rx_sr[6:0] <= rx_sr[7:1];
  271. // Majority vote of three samples
  272. rx_sr[7] <= (rx_bits[1] & rx_bits[0]) |
  273. (rx_bits[2] & rx_bits[0]) |
  274. (rx_bits[2] & rx_bits[1]);
  275. rx_ctr <= rx_ctr - 1'b1;
  276. // Push to FIFO if this was the bit before stop
  277. rx_recv_strb <= rx_ctr == 4'd2;
  278. end // if ( &rx_phase )
  279. end // if ( tty_clk_en_q )
  280. end // else: !if(~rst_n)
  281. end // if (ENABLE_RX_DATA)
  282. endgenerate
  283. endmodule // serial