serial.sv 7.4 KB

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