e1_rx.v 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * e1_rx.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * E1 RX top-level
  7. *
  8. *
  9. * Copyright (C) 2019 Sylvain Munaut <tnt@246tNt.com>
  10. * All rights reserved.
  11. *
  12. * LGPL v3+, see LICENSE.lgpl3
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU Lesser General Public
  16. * License as published by the Free Software Foundation; either
  17. * version 3 of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22. * Lesser General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Lesser General Public License
  25. * along with this program; if not, write to the Free Software Foundation,
  26. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  27. */
  28. `default_nettype none
  29. module e1_rx #(
  30. parameter integer LIU = 0,
  31. parameter integer MFW = 7
  32. )(
  33. // IO pads
  34. // Raw PHY
  35. input wire pad_rx_hi_p,
  36. input wire pad_rx_hi_n,
  37. input wire pad_rx_lo_p,
  38. input wire pad_rx_lo_n,
  39. // LIU
  40. input wire pad_rx_data,
  41. input wire pad_rx_clk,
  42. // Buffer interface
  43. output wire [7:0] buf_data,
  44. output wire [4:0] buf_ts,
  45. output wire [3:0] buf_frame,
  46. output wire [MFW-1:0] buf_mf,
  47. output wire buf_we,
  48. input wire buf_rdy,
  49. // BD interface
  50. input wire [MFW-1:0] bd_mf,
  51. output reg [1:0] bd_crc_e,
  52. input wire bd_valid,
  53. output reg bd_done,
  54. output reg bd_miss,
  55. // Loopback output
  56. output wire lb_bit,
  57. output wire lb_valid,
  58. // Status
  59. output wire status_aligned,
  60. // Common
  61. input wire clk,
  62. input wire rst
  63. );
  64. // Signals
  65. // -------
  66. // Low level (input -> bits)
  67. wire ll_raw_hi, ll_raw_lo;
  68. wire ll_flt_hi, ll_flt_lo, ll_flt_stb;
  69. wire ll_cdr_hi, ll_cdr_lo, ll_cdr_stb;
  70. wire ll_bit;
  71. wire ll_valid;
  72. // Deframer
  73. wire [7:0] df_data;
  74. wire [3:0] df_frame;
  75. wire [4:0] df_ts;
  76. wire df_ts_is0;
  77. wire df_first;
  78. wire df_last;
  79. wire df_valid;
  80. wire df_err_crc;
  81. wire df_err_mfa;
  82. wire df_err_fas;
  83. wire df_err_nfas;
  84. wire df_aligned;
  85. // Buffer Descriptor handling
  86. reg mf_valid;
  87. // Low-level bit recovery
  88. // ----------------------
  89. generate
  90. if (LIU == 0) begin
  91. // PHY
  92. e1_rx_phy phy_I (
  93. .pad_rx_hi_p(pad_rx_hi_p),
  94. .pad_rx_hi_n(pad_rx_hi_n),
  95. .pad_rx_lo_p(pad_rx_lo_p),
  96. .pad_rx_lo_n(pad_rx_lo_n),
  97. .rx_hi(ll_raw_hi),
  98. .rx_lo(ll_raw_lo),
  99. .clk(clk),
  100. .rst(rst)
  101. );
  102. // Glitch filtering
  103. e1_rx_filter filter_I (
  104. .in_hi(ll_raw_hi),
  105. .in_lo(ll_raw_lo),
  106. .out_hi(ll_flt_hi),
  107. .out_lo(ll_flt_lo),
  108. .out_stb(ll_flt_stb),
  109. .clk(clk),
  110. .rst(rst)
  111. );
  112. // Clock recovery
  113. e1_rx_clock_recovery clock_I (
  114. .in_hi(ll_flt_hi),
  115. .in_lo(ll_flt_lo),
  116. .in_stb(ll_flt_stb),
  117. .out_hi(ll_cdr_hi),
  118. .out_lo(ll_cdr_lo),
  119. .out_stb(ll_cdr_stb),
  120. .clk(clk),
  121. .rst(rst)
  122. );
  123. // HDB3 decoding
  124. hdb3_dec hdb3_I (
  125. .in_pos(ll_cdr_hi),
  126. .in_neg(ll_cdr_lo),
  127. .in_valid(ll_cdr_stb),
  128. .out_data(ll_bit),
  129. .out_valid(ll_valid),
  130. .clk(clk),
  131. .rst(rst)
  132. );
  133. end else begin
  134. // LIU interface
  135. e1_rx_liu liuif_I (
  136. .pad_rx_data(pad_rx_data),
  137. .pad_rx_clk(pad_rx_clk),
  138. .out_data(ll_bit),
  139. .out_valid(ll_valid),
  140. .clk(clk),
  141. .rst(rst)
  142. );
  143. end
  144. endgenerate
  145. // Loopback output
  146. assign lb_bit = ll_bit;
  147. assign lb_valid = ll_valid;
  148. // High-level frame recovery
  149. // -------------------------
  150. // Deframer
  151. e1_rx_deframer deframer_I (
  152. .in_bit(ll_bit),
  153. .in_valid(ll_valid),
  154. .out_data(df_data),
  155. .out_frame(df_frame),
  156. .out_ts(df_ts),
  157. .out_ts_is0(df_ts_is0),
  158. .out_first(df_first),
  159. .out_last(df_last),
  160. .out_valid(df_valid),
  161. .out_err_crc(df_err_crc),
  162. .out_err_mfa(df_err_mfa),
  163. .out_err_fas(df_err_fas),
  164. .out_err_nfas(df_err_nfas),
  165. .aligned(df_aligned),
  166. .clk(clk),
  167. .rst(rst)
  168. );
  169. // Buffer Descriptor
  170. // Keep track if we have a valid MF capture
  171. always @(posedge clk or posedge rst)
  172. if (rst)
  173. mf_valid <= 1'b0;
  174. else
  175. mf_valid <= ((df_valid & df_first) ? bd_valid : mf_valid) & df_aligned;
  176. // We register those because a 1 cycle delay doesn't matter
  177. // (we won't get another byte write for ~ 120 cycle)
  178. always @(posedge clk)
  179. begin
  180. bd_done <= df_valid & df_last & mf_valid;
  181. bd_miss <= df_valid & df_first & ~bd_valid;
  182. end
  183. // Track the CRC status of the two SMF
  184. always @(posedge clk or posedge rst)
  185. if (rst)
  186. bd_crc_e <= 2'b00;
  187. else
  188. bd_crc_e <= (bd_done) ? 2'b00 : (bd_crc_e | {
  189. df_valid & df_err_crc & df_frame[3], // CRC error in second SMF
  190. df_valid & df_err_crc & ~df_frame[3] // CRC error in first SMF
  191. });
  192. // Buffer write
  193. assign buf_data = df_data;
  194. assign buf_ts = df_ts;
  195. assign buf_frame = df_frame;
  196. assign buf_mf = bd_mf;
  197. assign buf_we = df_valid & bd_valid;
  198. // Status output
  199. assign status_aligned = df_aligned;
  200. endmodule // e1_rx