e1_tx_framer.v 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * e1_tx_framer.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * E1 Frame generation as described G.704
  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_framer (
  30. // Fetch interface
  31. input wire [7:0] in_data,
  32. input wire [1:0] in_crc_e, // CRC error bits to use in this multiframe
  33. output wire [3:0] in_frame,
  34. output wire [4:0] in_ts,
  35. output reg in_mf_first, // First request for this multiframe
  36. output reg in_mf_last, // Last request for this multiframe
  37. output reg in_req,
  38. input wire in_rdy,
  39. // Output
  40. output reg out_bit,
  41. output reg out_valid,
  42. // Loopback Input
  43. input wire lb_bit,
  44. input wire lb_valid,
  45. // Control
  46. input wire ctrl_time_src, // 0=internal, 1=external
  47. input wire ctrl_do_framing,
  48. input wire ctrl_do_crc4,
  49. input wire ctrl_loopback,
  50. input wire alarm,
  51. // Timing sources
  52. input wire ext_tick,
  53. output wire int_tick,
  54. // Common
  55. input wire clk,
  56. input wire rst
  57. );
  58. // Signals
  59. // -------
  60. // Tick source
  61. reg [5:0] tick_cnt;
  62. reg strobe;
  63. // Fetch unit
  64. reg [3:0] fetch_frame;
  65. reg [4:0] fetch_ts;
  66. reg fetch_ts_is0;
  67. reg fetch_ts_is31;
  68. reg fetch_first;
  69. reg fetch_last;
  70. reg fetch_done;
  71. wire [7:0] fetch_data;
  72. wire [1:0] fetch_crc_e;
  73. wire fetch_valid;
  74. wire fetch_ack;
  75. // TS0 generation
  76. reg [7:0] shift_data_nxt;
  77. wire [7:0] odd_bit0;
  78. // Shift register
  79. reg [7:0] shift_data;
  80. reg shift_at_first;
  81. reg shift_at_last;
  82. reg shift_at_crc;
  83. // CRC4
  84. wire crc_in_bit;
  85. wire crc_in_first;
  86. wire crc_in_valid;
  87. reg crc_capture;
  88. wire [3:0] crc_out;
  89. reg [3:0] crc_smf;
  90. // Tick source
  91. // -----------
  92. always @(posedge clk or posedge rst)
  93. if (rst)
  94. tick_cnt <= 5'b00000;
  95. else
  96. tick_cnt <= strobe ? 5'b01100 : (tick_cnt - 1);
  97. always @(posedge clk)
  98. strobe <= (ctrl_time_src ? ext_tick : tick_cnt[4]) & ~strobe;
  99. assign int_tick = strobe;
  100. // Fetch control
  101. // -------------
  102. // Frame
  103. always @(posedge clk or posedge rst)
  104. if (rst)
  105. fetch_frame <= 4'hf;
  106. else if (fetch_ack)
  107. fetch_frame <= fetch_frame + fetch_ts_is31;
  108. // Time Slot
  109. always @(posedge clk or posedge rst)
  110. if (rst) begin
  111. fetch_ts <= 5'h1f;
  112. fetch_ts_is0 <= 1'b0;
  113. fetch_ts_is31 <= 1'b1;
  114. end else if (fetch_ack) begin
  115. fetch_ts <= fetch_ts + 1;
  116. fetch_ts_is0 <= fetch_ts_is31;
  117. fetch_ts_is31 <= (fetch_ts == 5'h1e);
  118. end
  119. // External request
  120. assign in_frame = fetch_frame;
  121. assign in_ts = fetch_ts;
  122. always @(posedge clk or posedge rst)
  123. if (rst) begin
  124. in_mf_first <= 1'b0;
  125. in_mf_last <= 1'b1;
  126. end else if (fetch_ack) begin
  127. in_mf_first <= in_mf_last;
  128. in_mf_last <= (fetch_frame == 4'hf) && (fetch_ts == 5'h1e) ;
  129. end
  130. always @(posedge clk)
  131. in_req <= fetch_ack;
  132. // Track the first ever request (hence first valid data ...)
  133. always @(posedge clk or posedge rst)
  134. if (rst)
  135. fetch_done <= 1'b0;
  136. else if (in_req)
  137. fetch_done <= 1'b1;
  138. // Data output to next stage
  139. assign fetch_data = in_data;
  140. assign fetch_crc_e = in_crc_e;
  141. assign fetch_valid = in_rdy & fetch_done;
  142. // TS0 generation
  143. // --------------
  144. // After fetch_ack we have plenty of time to generate the next data
  145. // from the response
  146. assign odd_bit0 = { fetch_crc_e[1:0], 6'b110100 };
  147. always @(posedge clk)
  148. if (fetch_valid) begin
  149. if (fetch_ts_is0 & ctrl_do_framing) begin
  150. // TS0 with auto-framing
  151. if (fetch_frame[0])
  152. // Odd frame number
  153. shift_data_nxt <= { odd_bit0[fetch_frame[3:1]], 1'b1, alarm, 5'b11111 };
  154. else
  155. // Even frame number
  156. shift_data_nxt <= 8'h1b; // CRC bits are set later
  157. end else begin
  158. // Either auto-frame is disabled, or this is not TS0
  159. shift_data_nxt <= fetch_data;
  160. end
  161. end else begin
  162. // No data from fetch unit, fill with 0xff
  163. shift_data_nxt <= 8'hff;
  164. end
  165. // Shift register
  166. // --------------
  167. reg [3:0] bit_cnt;
  168. reg bit_first;
  169. // Bit counter
  170. always @(posedge clk or posedge rst)
  171. if (rst)
  172. bit_cnt <= 4'b1000;
  173. else if (strobe)
  174. bit_cnt <= bit_cnt[3] ? 4'b0110 : (bit_cnt - 1);
  175. // Shift register
  176. always @(posedge clk or posedge rst)
  177. if (rst)
  178. shift_data <= 8'hff;
  179. else if (strobe)
  180. shift_data <= bit_cnt[3] ? shift_data_nxt : { shift_data[6:0], 1'b1 };
  181. // Ack to upstream
  182. assign fetch_ack = strobe & bit_cnt[3];
  183. // Track special positions
  184. always @(posedge clk or posedge rst)
  185. if (rst) begin
  186. shift_at_first <= 1'b1;
  187. shift_at_last <= 1'b0;
  188. shift_at_crc <= 1'b0;
  189. end else if (strobe) begin
  190. shift_at_first <= (fetch_frame[2:0] == 3'b000) & fetch_ts_is0 & bit_cnt[3];
  191. shift_at_last <= (fetch_frame[2:0] == 3'b000) & fetch_ts_is0 & (bit_cnt[2:0] == 3'b000);
  192. shift_at_crc <= ~fetch_frame[0] & fetch_ts_is0 & bit_cnt[3];
  193. end
  194. // CRC4
  195. // ----
  196. // CRC4 computation
  197. assign crc_in_bit = shift_at_crc ? 1'b0 : shift_data[7];
  198. assign crc_in_first = shift_at_first;
  199. assign crc_in_valid = strobe;
  200. always @(posedge clk)
  201. crc_capture <= shift_at_last;
  202. e1_crc4 crc_I (
  203. .in_bit(crc_in_bit),
  204. .in_first(crc_in_first),
  205. .in_valid(crc_in_valid),
  206. .out_crc4(crc_out),
  207. .clk(clk),
  208. .rst(rst)
  209. );
  210. always @(posedge clk or posedge rst)
  211. if (rst)
  212. crc_smf <= 4'b1111;
  213. else if (crc_capture)
  214. crc_smf <= crc_out;
  215. else if (shift_at_crc & strobe)
  216. crc_smf <= { crc_smf[2:0], 1'b1 };
  217. // Output
  218. // ------
  219. always @(posedge clk or posedge rst)
  220. if (rst) begin
  221. out_bit <= 1'b1;
  222. out_valid <= 1'b0;
  223. end else begin
  224. out_bit <= ctrl_loopback ? lb_bit : ((ctrl_do_crc4 & shift_at_crc) ? crc_smf[3] : shift_data[7]);
  225. out_valid <= ctrl_loopback ? lb_valid : strobe;
  226. end
  227. endmodule // e1_tx_framer