You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
6.9 KiB

2 years ago
  1. module src_timecode_parser #(
  2. parameter REG_START_ADD = 0
  3. ) (
  4. input clk, //clock input
  5. input rst_n, //asynchronous reset input, low active
  6. //regbus interface
  7. output reg [31:0] addr,
  8. input [31:0] wr_data,
  9. input wr_en,
  10. inout wire [31:0] rd_data, //received serial data
  11. // 输入
  12. input timecode_signal_in,
  13. //输出
  14. output wire timecode_signal_orgin_output, //ttl原始数据
  15. output wire timecode_freq_trigger_signal
  16. );
  17. /*******************************************************************************
  18. * 寄存器读写 *
  19. *******************************************************************************/
  20. //
  21. // @功能:
  22. // 1. 采样TIMECODE信号
  23. // 2. 转发TIMECODE信号
  24. // 3. TIMECODE信号成功解析
  25. // 4. TIMECODE采样计数
  26. //
  27. // @寄存器列表:
  28. // 地址 读写 默认 描述
  29. // 0x00 wr 0x0 timecode bit周期
  30. // 0x01 r 0x0 flag bit[0]:timecode_ready_flag
  31. // 0x02 r 0x0 timecode [31:0]
  32. // 0x03 r 0x0 timecode [63:32]
  33. // 0x04 r 0x0 timecode_ready_signal_pluse_width //识别到一帧timecode信号后输出一个脉冲信号用于同步其他模块
  34. parameter REG_TIMECODE_BIT_PERIOD_ADD = REG_START_ADD + 0; //timecode bit周期寄存器地址
  35. parameter ADD_NUM = 5; //寄存器数量
  36. parameter REG_END_ADD = REG_START_ADD + ADD_NUM - 1; //寄存器结束地址
  37. reg [31:0] register[REG_START_ADD:REG_END_ADD];
  38. integer i;
  39. always @(posedge clk or negedge rst_n) begin
  40. if (!rst_n) begin
  41. for (i = 0; i < ADD_NUM; i = i + 1) begin
  42. register[i] <= 0;
  43. end
  44. end else begin
  45. if (wr_en && addr >= REG_START_ADD && addr <= REG_END_ADD) register[addr] <= wr_data;
  46. end
  47. end
  48. assign rd_data = (addr >= REG_START_ADD && addr <= REG_END_ADD) ? register[addr] : 31'bz;
  49. // 416us 500us 520us
  50. // 边沿触发--> 采样偏移同步
  51. //
  52. // 416us采用 160byte 采样到同步
  53. // 电平变化修正采样计数
  54. //
  55. // 配置:
  56. // 1. 制式
  57. // 2.
  58. // 边沿信号捕获
  59. reg [160-1:0] tc_bit_2x; //timecode 每1/2bit
  60. reg [79:0] tc_bit; //timecode 每1bit
  61. reg sample_signal; //采样信号
  62. reg [31:0] sample_time_cnt; //采样计数
  63. wire sample_time_calibrate_signal; //采样信号修正器
  64. reg time_code_signal_edge; //timecode原始信号的边沿信号即timecode上升沿或者下降沿时置1
  65. assign timecode_signal_in_a = timecode_signal_in; //
  66. reg timecode_signal_in_b; //
  67. reg tc_sync_signal_edge; // timecode捕获到同步信号时置1此时可以解析timecode信号并将其存放到寄存中
  68. /*******************************************************************************
  69. * timecode边沿信号捕获 *
  70. *******************************************************************************/
  71. always @(posedge clk or negedge rst_n) begin
  72. if (!rst_n) begin
  73. timecode_signal_in_b <= 0;
  74. end else begin
  75. timecode_signal_in_b <= timecode_signal_in_a;
  76. end
  77. end
  78. always @(posedge clk or negedge rst_n) begin
  79. if (!rst_n) begin
  80. time_code_signal_edge <= 0;
  81. end else begin
  82. if (timecode_signal_in_a != timecode_signal_in_b) begin
  83. time_code_signal_edge <= 1;
  84. end else begin
  85. time_code_signal_edge <= 0;
  86. end
  87. end
  88. end
  89. assign sample_time_calibrate_signal = time_code_signal_edge;
  90. /*******************************************************************************
  91. * BIT信号映射 *
  92. *******************************************************************************/
  93. //
  94. // 采样点 采样点 采样点 采样点
  95. // + + + +
  96. // ___------------_______--------
  97. // 0 1
  98. // timecode的每个bit要通过两个点进行判断所以需要2x的采样率
  99. //
  100. always @(*) begin
  101. for (i = 0; i < 79; i = i + 1) begin
  102. tc_bit[i] = !tc_bit_2x[i*2] & tc_bit_2x[i*2+1];
  103. end
  104. end
  105. /*******************************************************************************
  106. * 采样信号生成器 *
  107. *******************************************************************************/
  108. //
  109. // 1. 当捕获到timecode原始信号的边沿时校准采样信号计数器
  110. // 2. 当采样信号计数器到达采样点时输出采样信号
  111. // 3. 当采样信号计数器到达2倍采样点时重置采样信号计数器
  112. //
  113. assign timecode_sample_cnt_reset_signal = (
  114. sample_time_calibrate_signal||
  115. sample_time_cnt >= (register[REG_TIMECODE_BIT_PERIOD_ADD] << 1)
  116. );
  117. always @(posedge clk or negedge rst_n) begin
  118. if (!rst_n) begin
  119. sample_time_cnt <= 0;
  120. sample_signal <= 0;
  121. end else begin
  122. if (timecode_sample_cnt_reset_signal) begin
  123. sample_time_cnt <= 0;
  124. sample_signal <= 0;
  125. end else if (sample_time_cnt == register[REG_TIMECODE_BIT_PERIOD_ADD]) begin
  126. sample_time_cnt <= sample_time_cnt + 1;
  127. sample_signal <= 1;
  128. end else begin
  129. sample_time_cnt <= sample_time_cnt + 1;
  130. sample_signal <= 0;
  131. end
  132. end
  133. end
  134. //
  135. // 根据sample_signal捕获timecode信号
  136. //
  137. always @(posedge clk or negedge rst_n) begin
  138. if (!rst_n) begin
  139. tc_bit_2x <= 0;
  140. end else begin
  141. if (sample_signal) begin
  142. tc_bit_2x <= {tc_bit_2x[158:0], timecode_signal_in};
  143. end else begin
  144. tc_bit_2x <= tc_bit_2x;
  145. end
  146. end
  147. end
  148. /*******************************************************************************
  149. * tc_sync_signal_edge *
  150. *******************************************************************************/
  151. // ___------------_______--------
  152. // 0 1
  153. //
  154. // 捕获timecode同步信号
  155. //
  156. // 同步信号
  157. // 0011_1111_11111_1101
  158. // 1111_0101__0101_0101__0101_0101__0101_1101
  159. //
  160. reg [31:0] sync_code_pattern = 32'b1111_0101__0101_0101__0101_0101__0101_1101;
  161. assign tc_sync_signal = (tc_bit == sync_code_pattern);
  162. reg tc_sync_signal_b;
  163. always @(posedge clk or negedge rst_n) begin
  164. if (!rst_n) begin
  165. tc_sync_signal_b <= 0;
  166. end else begin
  167. tc_sync_signal_b <= tc_sync_signal;
  168. if (tc_sync_signal & !tc_sync_signal_b) begin
  169. tc_sync_signal_edge <= 1;
  170. end else begin
  171. tc_sync_signal_edge <= 0;
  172. end
  173. end
  174. end
  175. assign timecode_freq_trigger_signal = tc_sync_signal_edge;
  176. endmodule