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
208 lines
6.9 KiB
module src_timecode_parser #(
|
|
parameter REG_START_ADD = 0
|
|
) (
|
|
input clk, //clock input
|
|
input rst_n, //asynchronous reset input, low active
|
|
|
|
//regbus interface
|
|
output reg [31:0] addr,
|
|
input [31:0] wr_data,
|
|
input wr_en,
|
|
|
|
inout wire [31:0] rd_data, //received serial data
|
|
// 输入
|
|
input timecode_signal_in,
|
|
//输出
|
|
output wire timecode_signal_orgin_output, //ttl原始数据
|
|
output wire timecode_freq_trigger_signal
|
|
);
|
|
|
|
/*******************************************************************************
|
|
* 寄存器读写 *
|
|
*******************************************************************************/
|
|
|
|
//
|
|
// @功能:
|
|
// 1. 采样TIMECODE信号
|
|
// 2. 转发TIMECODE信号
|
|
// 3. TIMECODE信号成功解析
|
|
// 4. TIMECODE采样计数
|
|
//
|
|
// @寄存器列表:
|
|
// 地址 读写 默认 描述
|
|
// 0x00 wr 0x0 timecode bit周期
|
|
// 0x01 r 0x0 flag bit[0]:timecode_ready_flag
|
|
// 0x02 r 0x0 timecode [31:0]
|
|
// 0x03 r 0x0 timecode [63:32]
|
|
// 0x04 r 0x0 timecode_ready_signal_pluse_width //识别到一帧timecode信号后,输出一个脉冲信号,用于同步其他模块
|
|
|
|
parameter REG_TIMECODE_BIT_PERIOD_ADD = REG_START_ADD + 0; //timecode bit周期寄存器地址
|
|
|
|
|
|
parameter ADD_NUM = 5; //寄存器数量
|
|
parameter REG_END_ADD = REG_START_ADD + ADD_NUM - 1; //寄存器结束地址
|
|
reg [31:0] register[REG_START_ADD:REG_END_ADD];
|
|
integer i;
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
for (i = 0; i < ADD_NUM; i = i + 1) begin
|
|
register[i] <= 0;
|
|
end
|
|
end else begin
|
|
if (wr_en && addr >= REG_START_ADD && addr <= REG_END_ADD) register[addr] <= wr_data;
|
|
end
|
|
end
|
|
assign rd_data = (addr >= REG_START_ADD && addr <= REG_END_ADD) ? register[addr] : 31'bz;
|
|
|
|
|
|
|
|
// 416us 500us 520us
|
|
// 边沿触发--> 采样偏移同步
|
|
//
|
|
|
|
// 416us采用 160byte 采样到同步
|
|
// 电平变化修正采样计数
|
|
|
|
//
|
|
// 配置:
|
|
// 1. 制式
|
|
// 2.
|
|
|
|
// 边沿信号捕获
|
|
|
|
|
|
reg [160-1:0] tc_bit_2x; //timecode 每1/2bit
|
|
reg [79:0] tc_bit; //timecode 每1bit
|
|
reg sample_signal; //采样信号
|
|
reg [31:0] sample_time_cnt; //采样计数
|
|
wire sample_time_calibrate_signal; //采样信号修正器
|
|
reg time_code_signal_edge; //timecode原始信号的边沿信号,即timecode上升沿或者下降沿时,置1
|
|
assign timecode_signal_in_a = timecode_signal_in; //
|
|
reg timecode_signal_in_b; //
|
|
reg tc_sync_signal_edge; // timecode捕获到同步信号时,置1,此时可以解析timecode信号,并将其存放到寄存中
|
|
|
|
|
|
/*******************************************************************************
|
|
* timecode边沿信号捕获 *
|
|
*******************************************************************************/
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
timecode_signal_in_b <= 0;
|
|
end else begin
|
|
timecode_signal_in_b <= timecode_signal_in_a;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
time_code_signal_edge <= 0;
|
|
end else begin
|
|
if (timecode_signal_in_a != timecode_signal_in_b) begin
|
|
time_code_signal_edge <= 1;
|
|
end else begin
|
|
time_code_signal_edge <= 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
assign sample_time_calibrate_signal = time_code_signal_edge;
|
|
|
|
|
|
/*******************************************************************************
|
|
* BIT信号映射 *
|
|
*******************************************************************************/
|
|
//
|
|
// 采样点 采样点 采样点 采样点
|
|
// + + + +
|
|
// ___------------_______--------
|
|
// 0 1
|
|
// timecode的每个bit要通过两个点进行判断,所以需要2x的采样率
|
|
//
|
|
always @(*) begin
|
|
for (i = 0; i < 79; i = i + 1) begin
|
|
tc_bit[i] = !tc_bit_2x[i*2] & tc_bit_2x[i*2+1];
|
|
end
|
|
end
|
|
|
|
/*******************************************************************************
|
|
* 采样信号生成器 *
|
|
*******************************************************************************/
|
|
//
|
|
// 1. 当捕获到timecode原始信号的边沿时,校准采样信号计数器
|
|
// 2. 当采样信号计数器到达采样点时,输出采样信号
|
|
// 3. 当采样信号计数器到达2倍采样点时,重置采样信号计数器
|
|
//
|
|
assign timecode_sample_cnt_reset_signal = (
|
|
sample_time_calibrate_signal||
|
|
sample_time_cnt >= (register[REG_TIMECODE_BIT_PERIOD_ADD] << 1)
|
|
);
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
sample_time_cnt <= 0;
|
|
sample_signal <= 0;
|
|
end else begin
|
|
if (timecode_sample_cnt_reset_signal) begin
|
|
sample_time_cnt <= 0;
|
|
sample_signal <= 0;
|
|
end else if (sample_time_cnt == register[REG_TIMECODE_BIT_PERIOD_ADD]) begin
|
|
sample_time_cnt <= sample_time_cnt + 1;
|
|
sample_signal <= 1;
|
|
end else begin
|
|
sample_time_cnt <= sample_time_cnt + 1;
|
|
sample_signal <= 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
//
|
|
// 根据sample_signal捕获timecode信号
|
|
//
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
tc_bit_2x <= 0;
|
|
end else begin
|
|
if (sample_signal) begin
|
|
tc_bit_2x <= {tc_bit_2x[158:0], timecode_signal_in};
|
|
end else begin
|
|
tc_bit_2x <= tc_bit_2x;
|
|
end
|
|
end
|
|
end
|
|
|
|
/*******************************************************************************
|
|
* tc_sync_signal_edge *
|
|
*******************************************************************************/
|
|
// ___------------_______--------
|
|
// 0 1
|
|
//
|
|
// 捕获timecode同步信号
|
|
//
|
|
// 同步信号
|
|
// 0011_1111_11111_1101
|
|
// 1111_0101__0101_0101__0101_0101__0101_1101
|
|
//
|
|
reg [31:0] sync_code_pattern = 32'b1111_0101__0101_0101__0101_0101__0101_1101;
|
|
assign tc_sync_signal = (tc_bit == sync_code_pattern);
|
|
reg tc_sync_signal_b;
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
tc_sync_signal_b <= 0;
|
|
end else begin
|
|
tc_sync_signal_b <= tc_sync_signal;
|
|
|
|
if (tc_sync_signal & !tc_sync_signal_b) begin
|
|
tc_sync_signal_edge <= 1;
|
|
end else begin
|
|
tc_sync_signal_edge <= 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
assign timecode_freq_trigger_signal = tc_sync_signal_edge;
|
|
|
|
|
|
|
|
endmodule
|