e1_tx.v 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * e1_tx.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * E1 TX 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_tx #(
  30. parameter integer LIU = 0,
  31. parameter integer MFW = 7
  32. )(
  33. // IO pads
  34. // Raw PHY
  35. output wire pad_tx_hi,
  36. output wire pad_tx_lo,
  37. // LIU
  38. output wire pad_tx_data,
  39. output wire pad_tx_clk,
  40. // Buffer interface
  41. input wire [7:0] buf_data,
  42. output wire [4:0] buf_ts,
  43. output wire [3:0] buf_frame,
  44. output wire [MFW-1:0] buf_mf,
  45. output wire buf_re,
  46. input wire buf_rdy,
  47. // BD interface
  48. input wire [MFW-1:0] bd_mf,
  49. input wire [1:0] bd_crc_e,
  50. input wire bd_valid,
  51. output reg bd_done,
  52. output reg bd_miss,
  53. // Loopback input
  54. input wire lb_bit,
  55. input wire lb_valid,
  56. // Control
  57. input wire ctrl_time_src, // 0=internal, 1=external
  58. input wire ctrl_do_framing,
  59. input wire ctrl_do_crc4,
  60. input wire ctrl_loopback,
  61. input wire alarm,
  62. // Timing sources
  63. input wire ext_tick,
  64. output wire int_tick,
  65. // Common
  66. input wire clk,
  67. input wire rst
  68. );
  69. // Signals
  70. // -------
  71. // Buffer Descriptor handling
  72. reg mf_valid;
  73. // Framer
  74. wire [7:0] f_data;
  75. wire [1:0] f_crc_e;
  76. wire [3:0] f_frame;
  77. wire [4:0] f_ts;
  78. wire f_mf_first;
  79. wire f_mf_last;
  80. wire f_req;
  81. wire f_rdy;
  82. // Low-level (bit -> pulses)
  83. wire ll_bit, ll_valid;
  84. wire ll_pg_hi, ll_pg_lo, ll_pg_stb;
  85. wire ll_raw_hi, ll_raw_lo;
  86. // Pulse generator
  87. reg [4:0] pg_hi;
  88. reg [4:0] pg_lo;
  89. // Frame generation
  90. // ----------------
  91. // Buffer Descriptor
  92. // Keep track if we're in a valid MF at all
  93. always @(posedge clk or posedge rst)
  94. if (rst)
  95. mf_valid <= 1'b0;
  96. else if (f_req & f_mf_first)
  97. mf_valid <= bd_valid;
  98. // We register those because a 1 cycle delay doesn't matter
  99. always @(posedge clk)
  100. begin
  101. bd_done <= f_req & f_mf_last & mf_valid;
  102. bd_miss <= f_req & f_mf_first & ~bd_valid;
  103. end
  104. // Buffer read
  105. assign buf_ts = f_ts;
  106. assign buf_frame = f_frame;
  107. assign buf_mf = bd_mf;
  108. assign buf_re = f_req & bd_valid;
  109. assign f_data = buf_data;
  110. assign f_crc_e = bd_crc_e;
  111. assign f_rdy = buf_rdy & mf_valid;
  112. // Framer
  113. e1_tx_framer framer_I (
  114. .in_data(f_data),
  115. .in_crc_e(f_crc_e),
  116. .in_frame(f_frame),
  117. .in_ts(f_ts),
  118. .in_mf_first(f_mf_first),
  119. .in_mf_last(f_mf_last),
  120. .in_req(f_req),
  121. .in_rdy(f_rdy),
  122. .out_bit(ll_bit),
  123. .out_valid(ll_valid),
  124. .lb_bit(lb_bit),
  125. .lb_valid(lb_valid),
  126. .ctrl_time_src(ctrl_time_src),
  127. .ctrl_do_framing(ctrl_do_framing),
  128. .ctrl_do_crc4(ctrl_do_crc4),
  129. .ctrl_loopback(ctrl_loopback),
  130. .alarm(alarm),
  131. .ext_tick(ext_tick),
  132. .int_tick(int_tick),
  133. .clk(clk),
  134. .rst(rst)
  135. );
  136. // Low-level
  137. // ---------
  138. generate
  139. if (LIU == 0) begin
  140. // HDB3 encoding
  141. hdb3_enc hdb3_I (
  142. .out_pos(ll_pg_hi),
  143. .out_neg(ll_pg_lo),
  144. .out_valid(ll_pg_stb),
  145. .in_data(ll_bit),
  146. .in_valid(ll_valid),
  147. .clk(clk),
  148. .rst(rst)
  149. );
  150. // Pulse generation
  151. always @(posedge clk)
  152. begin
  153. if (rst) begin
  154. pg_hi <= 0;
  155. pg_lo <= 0;
  156. end else begin
  157. if (ll_pg_stb) begin
  158. pg_hi <= ll_pg_hi ? 5'h19 : 5'h00;
  159. pg_lo <= ll_pg_lo ? 5'h19 : 5'h00;
  160. end else begin
  161. pg_hi <= pg_hi - pg_hi[4];
  162. pg_lo <= pg_lo - pg_lo[4];
  163. end
  164. end
  165. end
  166. assign ll_raw_hi = pg_hi[4];
  167. assign ll_raw_lo = pg_lo[4];
  168. // PHY
  169. e1_tx_phy phy_I (
  170. .pad_tx_hi(pad_tx_hi),
  171. .pad_tx_lo(pad_tx_lo),
  172. .tx_hi(ll_raw_hi),
  173. .tx_lo(ll_raw_lo),
  174. .clk(clk),
  175. .rst(rst)
  176. );
  177. end else begin
  178. // LIU interface
  179. e1_tx_liu liuif_I (
  180. .pad_tx_data(pad_tx_data),
  181. .pad_tx_clk(pad_tx_clk),
  182. .in_data(ll_bit),
  183. .in_valid(ll_valid),
  184. .clk(clk),
  185. .rst(rst)
  186. );
  187. end
  188. endgenerate
  189. endmodule // e1_tx