e1_tx.v 4.0 KB

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