e1_rx.v 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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 MFW = 7
  31. )(
  32. // IO pads
  33. input wire pad_rx_hi_p,
  34. input wire pad_rx_hi_n,
  35. input wire pad_rx_lo_p,
  36. input wire pad_rx_lo_n,
  37. // Buffer interface
  38. output wire [7:0] buf_data,
  39. output wire [4:0] buf_ts,
  40. output wire [3:0] buf_frame,
  41. output wire [MFW-1:0] buf_mf,
  42. output wire buf_we,
  43. input wire buf_rdy,
  44. // BD interface
  45. input wire [MFW-1:0] bd_mf,
  46. output reg [1:0] bd_crc_e,
  47. input wire bd_valid,
  48. output reg bd_done,
  49. output reg bd_miss,
  50. // Loopback output
  51. output wire lb_bit,
  52. output wire lb_valid,
  53. // Status
  54. output wire status_aligned,
  55. // Common
  56. input wire clk,
  57. input wire rst
  58. );
  59. // Signals
  60. // -------
  61. // Low level (input -> bits)
  62. wire ll_raw_hi, ll_raw_lo;
  63. wire ll_flt_hi, ll_flt_lo, ll_flt_stb;
  64. wire ll_cdr_hi, ll_cdr_lo, ll_cdr_stb;
  65. wire ll_bit;
  66. wire ll_valid;
  67. // Deframer
  68. wire [7:0] df_data;
  69. wire [3:0] df_frame;
  70. wire [4:0] df_ts;
  71. wire df_ts_is0;
  72. wire df_first;
  73. wire df_last;
  74. wire df_valid;
  75. wire df_err_crc;
  76. wire df_err_mfa;
  77. wire df_err_fas;
  78. wire df_err_nfas;
  79. wire df_aligned;
  80. // Buffer Descriptor handling
  81. reg mf_valid;
  82. // Low-level bit recovery
  83. // ----------------------
  84. // PHY
  85. e1_rx_phy phy_I (
  86. .pad_rx_hi_p(pad_rx_hi_p),
  87. .pad_rx_hi_n(pad_rx_hi_n),
  88. .pad_rx_lo_p(pad_rx_lo_p),
  89. .pad_rx_lo_n(pad_rx_lo_n),
  90. .rx_hi(ll_raw_hi),
  91. .rx_lo(ll_raw_lo),
  92. .clk(clk),
  93. .rst(rst)
  94. );
  95. // Glitch filtering
  96. e1_rx_filter filter_I (
  97. .in_hi(ll_raw_hi),
  98. .in_lo(ll_raw_lo),
  99. .out_hi(ll_flt_hi),
  100. .out_lo(ll_flt_lo),
  101. .out_stb(ll_flt_stb),
  102. .clk(clk),
  103. .rst(rst)
  104. );
  105. // Clock recovery
  106. e1_rx_clock_recovery clock_I (
  107. .in_hi(ll_flt_hi),
  108. .in_lo(ll_flt_lo),
  109. .in_stb(ll_flt_stb),
  110. .out_hi(ll_cdr_hi),
  111. .out_lo(ll_cdr_lo),
  112. .out_stb(ll_cdr_stb),
  113. .clk(clk),
  114. .rst(rst)
  115. );
  116. // HDB3 decoding
  117. hdb3_dec hdb3_I (
  118. .in_pos(ll_cdr_hi),
  119. .in_neg(ll_cdr_lo),
  120. .in_valid(ll_cdr_stb),
  121. .out_data(ll_bit),
  122. .out_valid(ll_valid),
  123. .clk(clk),
  124. .rst(rst)
  125. );
  126. // Loopback output
  127. assign lb_bit = ll_bit;
  128. assign lb_valid = ll_valid;
  129. // High-level frame recovery
  130. // -------------------------
  131. // Deframer
  132. e1_rx_deframer deframer_I (
  133. .in_bit(ll_bit),
  134. .in_valid(ll_valid),
  135. .out_data(df_data),
  136. .out_frame(df_frame),
  137. .out_ts(df_ts),
  138. .out_ts_is0(df_ts_is0),
  139. .out_first(df_first),
  140. .out_last(df_last),
  141. .out_valid(df_valid),
  142. .out_err_crc(df_err_crc),
  143. .out_err_mfa(df_err_mfa),
  144. .out_err_fas(df_err_fas),
  145. .out_err_nfas(df_err_nfas),
  146. .aligned(df_aligned),
  147. .clk(clk),
  148. .rst(rst)
  149. );
  150. // Buffer Descriptor
  151. // Keep track if we have a valid MF capture
  152. always @(posedge clk or posedge rst)
  153. if (rst)
  154. mf_valid <= 1'b0;
  155. else
  156. mf_valid <= ((df_valid & df_first) ? bd_valid : mf_valid) & df_aligned;
  157. // We register those because a 1 cycle delay doesn't matter
  158. // (we won't get another byte write for ~ 120 cycle)
  159. always @(posedge clk)
  160. begin
  161. bd_done <= df_valid & df_last & mf_valid;
  162. bd_miss <= df_valid & df_first & ~bd_valid;
  163. end
  164. // Track the CRC status of the two SMF
  165. always @(posedge clk or posedge rst)
  166. if (rst)
  167. bd_crc_e <= 2'b00;
  168. else if (df_valid)
  169. bd_crc_e <= (bd_done) ? 2'b00 : (bd_crc_e | {
  170. df_err_crc & df_frame[3], // CRC error in second SMF
  171. df_err_crc & ~df_frame[3] // CRC error in first SMF
  172. });
  173. // Buffer write
  174. assign buf_data = df_data;
  175. assign buf_ts = df_ts;
  176. assign buf_frame = df_frame;
  177. assign buf_mf = bd_mf;
  178. assign buf_we = df_valid & bd_valid;
  179. // Status output
  180. assign status_aligned = df_aligned;
  181. endmodule // e1_rx