6 changed files with 502 additions and 113 deletions
-
142led_test.pds
-
193source/src/timecode/timecode_decoder.v
-
53source/src/timecode/timecode_sample_sig_generator.v
-
113source/src/timecode_input.v
-
30source/src/top.v
-
84source/test/test_timecode_decoder.v
@ -0,0 +1,193 @@ |
|||
module timecode_decoder #( |
|||
parameter SYS_CLOCK_FREQ = 10000000 |
|||
) ( |
|||
input clk, //clock input |
|||
input rst_n, //asynchronous reset input, low active |
|||
|
|||
input timecode_in, |
|||
output timecode_in_state, |
|||
|
|||
|
|||
/******************************************************************************* |
|||
* TIMECODE输出 * |
|||
*******************************************************************************/ |
|||
output reg timecode_tigger_sig, |
|||
output reg [63:0] timecode_data, |
|||
// output [31:0] timecode_format, |
|||
output timecode_serial_data |
|||
); |
|||
|
|||
// Rate 1/2Fe 1Fe |
|||
// 23.98 F/s 260.7 us 521.4 us |
|||
// 24.00 F/s 260.4 us 520.8 us |
|||
// 25.00 F/s 250.0 us 500.0 us |
|||
// 29.97 F/s 208.5 us 417.1 us |
|||
// 30.00 F/s 208.3 us 416.7 us |
|||
|
|||
// 260->520 -->130 |
|||
// 208->416 -->104 |
|||
// ---> 117us 351us |
|||
// |
|||
// 由于TIMECODE的频率范围是固定的,所以这里采用117,和351作为其采样点,这样既可以采样23.98也可以采样30.00 |
|||
// 对应的采样频率为1000000/117=8547HZ |
|||
// |
|||
|
|||
// 原始数据输出 |
|||
assign timecode_serial_data = timecode_in; |
|||
assign timecode_in_state = timecode_in; |
|||
|
|||
wire timecode_sample_sig_generator_rest_sig; |
|||
wire timecode_in_edge; |
|||
assign timecode_sample_sig_generator_rest_sig = !timecode_in_edge & rst_n; |
|||
zutils_edge_detecter _signal_in ( |
|||
.clk(clk), |
|||
.rst_n(rst_n), |
|||
.in_signal(timecode_in), |
|||
.in_signal_edge(timecode_in_edge) |
|||
); |
|||
wire sample_sig; |
|||
timecode_sample_sig_generator #( |
|||
.SYS_CLOCK_FREQ(SYS_CLOCK_FREQ), |
|||
.SAMPLE_RATE(854700) |
|||
) timecode_sample_sig_generator ( |
|||
.clk(clk), |
|||
.rst_n(timecode_sample_sig_generator_rest_sig), |
|||
.sample_sig(sample_sig) |
|||
); |
|||
|
|||
|
|||
// 采样+缓存采样数据 |
|||
reg [159:0] timecode_data_cache; |
|||
always @(posedge clk or negedge rst_n) begin |
|||
if (!rst_n) begin |
|||
timecode_data_cache <= 0; |
|||
end else begin |
|||
if (sample_sig) begin |
|||
timecode_data_cache <= {timecode_in,timecode_data_cache[159:1]}; |
|||
end else begin |
|||
timecode_data_cache <= timecode_data_cache; |
|||
end |
|||
end |
|||
end |
|||
|
|||
//译码 |
|||
reg [79:0] timecode_bit_cache; |
|||
// integer i; |
|||
always @(*) begin |
|||
// for (i = 0; i < 79; i = i + 1) begin |
|||
// timecode_bit_cache[i] = timecode_data_cache[i*2] & !timecode_data_cache[i*2+1]; |
|||
// end |
|||
|
|||
timecode_bit_cache[0] = timecode_data_cache[0] ^ timecode_data_cache[1]; |
|||
timecode_bit_cache[1] = timecode_data_cache[2] ^ timecode_data_cache[3]; |
|||
timecode_bit_cache[2] = timecode_data_cache[4] ^ timecode_data_cache[5]; |
|||
timecode_bit_cache[3] = timecode_data_cache[6] ^ timecode_data_cache[7]; |
|||
timecode_bit_cache[4] = timecode_data_cache[8] ^ timecode_data_cache[9]; |
|||
timecode_bit_cache[5] = timecode_data_cache[10] ^ timecode_data_cache[11]; |
|||
timecode_bit_cache[6] = timecode_data_cache[12] ^ timecode_data_cache[13]; |
|||
timecode_bit_cache[7] = timecode_data_cache[14] ^ timecode_data_cache[15]; |
|||
timecode_bit_cache[8] = timecode_data_cache[16] ^ timecode_data_cache[17]; |
|||
timecode_bit_cache[9] = timecode_data_cache[18] ^ timecode_data_cache[19]; |
|||
timecode_bit_cache[10] = timecode_data_cache[20] ^ timecode_data_cache[21]; |
|||
timecode_bit_cache[11] = timecode_data_cache[22] ^ timecode_data_cache[23]; |
|||
timecode_bit_cache[12] = timecode_data_cache[24] ^ timecode_data_cache[25]; |
|||
timecode_bit_cache[13] = timecode_data_cache[26] ^ timecode_data_cache[27]; |
|||
timecode_bit_cache[14] = timecode_data_cache[28] ^ timecode_data_cache[29]; |
|||
timecode_bit_cache[15] = timecode_data_cache[30] ^ timecode_data_cache[31]; |
|||
timecode_bit_cache[16] = timecode_data_cache[32] ^ timecode_data_cache[33]; |
|||
timecode_bit_cache[17] = timecode_data_cache[34] ^ timecode_data_cache[35]; |
|||
timecode_bit_cache[18] = timecode_data_cache[36] ^ timecode_data_cache[37]; |
|||
timecode_bit_cache[19] = timecode_data_cache[38] ^ timecode_data_cache[39]; |
|||
timecode_bit_cache[20] = timecode_data_cache[40] ^ timecode_data_cache[41]; |
|||
timecode_bit_cache[21] = timecode_data_cache[42] ^ timecode_data_cache[43]; |
|||
timecode_bit_cache[22] = timecode_data_cache[44] ^ timecode_data_cache[45]; |
|||
timecode_bit_cache[23] = timecode_data_cache[46] ^ timecode_data_cache[47]; |
|||
timecode_bit_cache[24] = timecode_data_cache[48] ^ timecode_data_cache[49]; |
|||
timecode_bit_cache[25] = timecode_data_cache[50] ^ timecode_data_cache[51]; |
|||
timecode_bit_cache[26] = timecode_data_cache[52] ^ timecode_data_cache[53]; |
|||
timecode_bit_cache[27] = timecode_data_cache[54] ^ timecode_data_cache[55]; |
|||
timecode_bit_cache[28] = timecode_data_cache[56] ^ timecode_data_cache[57]; |
|||
timecode_bit_cache[29] = timecode_data_cache[58] ^ timecode_data_cache[59]; |
|||
timecode_bit_cache[30] = timecode_data_cache[60] ^ timecode_data_cache[61]; |
|||
timecode_bit_cache[31] = timecode_data_cache[62] ^ timecode_data_cache[63]; |
|||
timecode_bit_cache[32] = timecode_data_cache[64] ^ timecode_data_cache[65]; |
|||
timecode_bit_cache[33] = timecode_data_cache[66] ^ timecode_data_cache[67]; |
|||
timecode_bit_cache[34] = timecode_data_cache[68] ^ timecode_data_cache[69]; |
|||
timecode_bit_cache[35] = timecode_data_cache[70] ^ timecode_data_cache[71]; |
|||
timecode_bit_cache[36] = timecode_data_cache[72] ^ timecode_data_cache[73]; |
|||
timecode_bit_cache[37] = timecode_data_cache[74] ^ timecode_data_cache[75]; |
|||
timecode_bit_cache[38] = timecode_data_cache[76] ^ timecode_data_cache[77]; |
|||
timecode_bit_cache[39] = timecode_data_cache[78] ^ timecode_data_cache[79]; |
|||
timecode_bit_cache[40] = timecode_data_cache[80] ^ timecode_data_cache[81]; |
|||
timecode_bit_cache[41] = timecode_data_cache[82] ^ timecode_data_cache[83]; |
|||
timecode_bit_cache[42] = timecode_data_cache[84] ^ timecode_data_cache[85]; |
|||
timecode_bit_cache[43] = timecode_data_cache[86] ^ timecode_data_cache[87]; |
|||
timecode_bit_cache[44] = timecode_data_cache[88] ^ timecode_data_cache[89]; |
|||
timecode_bit_cache[45] = timecode_data_cache[90] ^ timecode_data_cache[91]; |
|||
timecode_bit_cache[46] = timecode_data_cache[92] ^ timecode_data_cache[93]; |
|||
timecode_bit_cache[47] = timecode_data_cache[94] ^ timecode_data_cache[95]; |
|||
timecode_bit_cache[48] = timecode_data_cache[96] ^ timecode_data_cache[97]; |
|||
timecode_bit_cache[49] = timecode_data_cache[98] ^ timecode_data_cache[99]; |
|||
timecode_bit_cache[50] = timecode_data_cache[100] ^ timecode_data_cache[101]; |
|||
timecode_bit_cache[51] = timecode_data_cache[102] ^ timecode_data_cache[103]; |
|||
timecode_bit_cache[52] = timecode_data_cache[104] ^ timecode_data_cache[105]; |
|||
timecode_bit_cache[53] = timecode_data_cache[106] ^ timecode_data_cache[107]; |
|||
timecode_bit_cache[54] = timecode_data_cache[108] ^ timecode_data_cache[109]; |
|||
timecode_bit_cache[55] = timecode_data_cache[110] ^ timecode_data_cache[111]; |
|||
timecode_bit_cache[56] = timecode_data_cache[112] ^ timecode_data_cache[113]; |
|||
timecode_bit_cache[57] = timecode_data_cache[114] ^ timecode_data_cache[115]; |
|||
timecode_bit_cache[58] = timecode_data_cache[116] ^ timecode_data_cache[117]; |
|||
timecode_bit_cache[59] = timecode_data_cache[118] ^ timecode_data_cache[119]; |
|||
timecode_bit_cache[60] = timecode_data_cache[120] ^ timecode_data_cache[121]; |
|||
timecode_bit_cache[61] = timecode_data_cache[122] ^ timecode_data_cache[123]; |
|||
timecode_bit_cache[62] = timecode_data_cache[124] ^ timecode_data_cache[125]; |
|||
timecode_bit_cache[63] = timecode_data_cache[126] ^ timecode_data_cache[127]; |
|||
timecode_bit_cache[64] = timecode_data_cache[128] ^ timecode_data_cache[129]; |
|||
timecode_bit_cache[65] = timecode_data_cache[130] ^ timecode_data_cache[131]; |
|||
timecode_bit_cache[66] = timecode_data_cache[132] ^ timecode_data_cache[133]; |
|||
timecode_bit_cache[67] = timecode_data_cache[134] ^ timecode_data_cache[135]; |
|||
timecode_bit_cache[68] = timecode_data_cache[136] ^ timecode_data_cache[137]; |
|||
timecode_bit_cache[69] = timecode_data_cache[138] ^ timecode_data_cache[139]; |
|||
timecode_bit_cache[70] = timecode_data_cache[140] ^ timecode_data_cache[141]; |
|||
timecode_bit_cache[71] = timecode_data_cache[142] ^ timecode_data_cache[143]; |
|||
timecode_bit_cache[72] = timecode_data_cache[144] ^ timecode_data_cache[145]; |
|||
timecode_bit_cache[73] = timecode_data_cache[146] ^ timecode_data_cache[147]; |
|||
timecode_bit_cache[74] = timecode_data_cache[148] ^ timecode_data_cache[149]; |
|||
timecode_bit_cache[75] = timecode_data_cache[150] ^ timecode_data_cache[151]; |
|||
timecode_bit_cache[76] = timecode_data_cache[152] ^ timecode_data_cache[153]; |
|||
timecode_bit_cache[77] = timecode_data_cache[154] ^ timecode_data_cache[155]; |
|||
timecode_bit_cache[78] = timecode_data_cache[156] ^ timecode_data_cache[157]; |
|||
timecode_bit_cache[79] = timecode_data_cache[158] ^ timecode_data_cache[159]; |
|||
end |
|||
|
|||
// 识别信号捕获 |
|||
wire [15:0] synccode; |
|||
assign synccode = timecode_bit_cache[79:64]; |
|||
assign detect_sync_code = (synccode == 16'b1011_1111_1111_1100); |
|||
|
|||
|
|||
wire detect_sync_code_sig; |
|||
zutils_edge_detecter detect_sync_code_detect ( |
|||
.clk(clk), |
|||
.rst_n(rst_n), |
|||
.in_signal(detect_sync_code), |
|||
.in_signal_rising_edge(detect_sync_code_sig) |
|||
); |
|||
|
|||
//输出时码识别信号 |
|||
|
|||
always @(posedge clk or negedge rst_n) begin |
|||
if (!rst_n) begin |
|||
timecode_tigger_sig <= 0; |
|||
timecode_data <= 0; |
|||
end else begin |
|||
if (detect_sync_code_sig) begin |
|||
timecode_tigger_sig <= 1; |
|||
timecode_data <= timecode_bit_cache[63:0]; |
|||
end else begin |
|||
timecode_tigger_sig <= 0; |
|||
end |
|||
end |
|||
end |
|||
|
|||
endmodule |
@ -0,0 +1,53 @@ |
|||
module timecode_sample_sig_generator #( |
|||
parameter SYS_CLOCK_FREQ = 10000000, |
|||
parameter SAMPLE_RATE = 8547 |
|||
) ( |
|||
input clk, //clock input |
|||
input rst_n, //asynchronous reset input, low active |
|||
|
|||
output reg sample_sig |
|||
); |
|||
|
|||
|
|||
// |
|||
// sampleSig ______|____________|____________|____________| |
|||
// |
|||
|
|||
localparam COUNT = (SYS_CLOCK_FREQ * 100) / SAMPLE_RATE; |
|||
reg [31:0] counter; |
|||
reg [1:0] sub_counter; |
|||
|
|||
wire counter_clear; |
|||
always @(posedge clk or negedge rst_n) begin |
|||
if (!rst_n) begin |
|||
counter <= 0; |
|||
sub_counter <= 1; |
|||
end else begin |
|||
|
|||
if (counter == COUNT) begin |
|||
counter <= 0; |
|||
|
|||
if (sub_counter == 1) begin |
|||
sample_sig <= 1; |
|||
sub_counter <= 0; |
|||
end else begin |
|||
sub_counter <= 1; |
|||
end |
|||
|
|||
end else begin |
|||
counter <= counter + 1; |
|||
sample_sig <= 0; |
|||
end |
|||
|
|||
end |
|||
end |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,113 @@ |
|||
module timecode_input_parser #( |
|||
parameter REG_START_ADD = 0, |
|||
parameter SYS_CLOCK_FREQ = 10000000 |
|||
) ( |
|||
input clk, //clock input |
|||
input rst_n, //asynchronous reset input, low active |
|||
|
|||
//寄存器读写接口 |
|||
input [31:0] addr, |
|||
input [31:0] wr_data, |
|||
input wr_en, |
|||
output wire [31:0] rd_data, |
|||
|
|||
input timecode_bnc_in, |
|||
input timecode_headphone_in, |
|||
|
|||
/******************************************************************************* |
|||
* TIMECODE输出 * |
|||
*******************************************************************************/ |
|||
output timecode_tigger_sig, |
|||
output [31:0] timecode_format, |
|||
output [63:0] timecode_data, |
|||
output timecode_serial_data, |
|||
|
|||
/******************************************************************************* |
|||
* 指示灯状态输出 * |
|||
*******************************************************************************/ |
|||
output timecode_headphone_in_state_led, |
|||
output timecode_bnc_in_state_led |
|||
|
|||
); |
|||
|
|||
|
|||
reg [31:0] r0_timecode_sig_selt; //信号源选择 0:off,1:bnc,2:headphone |
|||
reg [31:0] r1_timecode_format; // |
|||
reg [31:0] r2_timecode0; // |
|||
reg [31:0] r3_timecode1; // |
|||
wire [31:0] reg_wr_index; |
|||
zutils_register_advanced #( |
|||
.REG_START_ADD(REG_START_ADD) |
|||
) _register ( |
|||
.clk(clk), |
|||
.rst_n(rst_n), |
|||
.addr(addr), |
|||
.wr_data(wr_data), |
|||
.wr_en(wr_en), |
|||
.rd_data(rd_data), |
|||
|
|||
.reg0(r0_timecode_sig_selt), |
|||
.reg1(r1_timecode_format), |
|||
.reg2(r2_timecode0), |
|||
.reg3(r3_timecode1), |
|||
|
|||
.reg_wr_sig(reg_wr_sig), |
|||
.reg_index (reg_wr_index) |
|||
); |
|||
|
|||
always @(posedge clk or negedge rst_n) begin |
|||
if (!rst_n) begin |
|||
r0_timecode_sig_selt <= 0; |
|||
r1_timecode_format <= 0; |
|||
end else begin |
|||
if (reg_wr_sig) begin |
|||
case (reg_wr_index) |
|||
31'h0: r0_timecode_sig_selt <= wr_data; |
|||
31'h1: r1_timecode_format <= wr_data; |
|||
default: begin |
|||
end |
|||
endcase |
|||
end |
|||
end |
|||
end |
|||
|
|||
wire timecode_in_af_selt; |
|||
zutils_multiplexer_4t1 _signal_select ( |
|||
.chooseindex(r0_timecode_sig_selt), |
|||
.signal0(1'b0), |
|||
.signal1(timecode_bnc_in), |
|||
.signal2(timecode_headphone_in), |
|||
.signalout(timecode_in_af_selt) |
|||
); |
|||
|
|||
timecode_decoder #( |
|||
.SYS_CLOCK_FREQ(10000000) |
|||
) timecode_decoder_ins ( |
|||
.clk(clk), |
|||
.rst_n(rst_n), |
|||
.timecode_in(timecode_in_af_selt), // 时码输入 |
|||
.timecode_tigger_sig(timecode_tigger_sig), // |
|||
.timecode_data(timecode_data), //[63:0] |
|||
.timecode_serial_data(timecode_serial_data) // |
|||
); |
|||
|
|||
|
|||
|
|||
always @(posedge clk or negedge rst_n) begin |
|||
if (!rst_n) begin |
|||
r2_timecode0 <= 0; |
|||
r3_timecode1 <= 0; |
|||
end else begin |
|||
if (timecode_tigger_sig) begin |
|||
r2_timecode0 <= timecode_data[31:0]; |
|||
r3_timecode1 <= timecode_data[63:32]; |
|||
end |
|||
end |
|||
end |
|||
|
|||
assign timecode_format = r1_timecode_format; |
|||
assign timecode_headphone_in_state_led = 1; |
|||
assign timecode_bnc_in_state_led = 1; |
|||
|
|||
|
|||
endmodule |
@ -0,0 +1,84 @@ |
|||
`timescale 10ns / 10ns |
|||
module test_timecode_decoder; |
|||
reg sys_clk; |
|||
reg rst_n; |
|||
|
|||
reg timecode_in; |
|||
|
|||
reg one_timecode_end; |
|||
reg datanow; |
|||
|
|||
wire timecode_in_state; |
|||
wire timecode_tigger_sig; |
|||
wire [63:0] timecode_data; |
|||
wire timecode_serial_data; |
|||
reg [7:0] offset; |
|||
|
|||
timecode_decoder #( |
|||
.SYS_CLOCK_FREQ(10000000) |
|||
) timecode_decoder_inst ( |
|||
.clk (sys_clk), |
|||
.rst_n(rst_n), |
|||
|
|||
.timecode_in(timecode_in), |
|||
.timecode_in_state(timecode_in_state), |
|||
|
|||
.timecode_tigger_sig(timecode_tigger_sig), |
|||
.timecode_data(timecode_data), |
|||
.timecode_serial_data(timecode_serial_data) |
|||
); |
|||
|
|||
|
|||
// 250us |
|||
task timecode_generator; |
|||
input [79:0] data; |
|||
integer i; |
|||
begin |
|||
for (i = 0; i < 80; i = i + 1) begin |
|||
offset = i; |
|||
if (data[i]) begin |
|||
datanow = 1; |
|||
end else begin |
|||
datanow = 0; |
|||
end |
|||
timecode_in = ~timecode_in; |
|||
#25000; |
|||
if (data[i]) begin |
|||
timecode_in = ~timecode_in; |
|||
end |
|||
#25000; |
|||
end |
|||
end |
|||
endtask |
|||
|
|||
initial begin |
|||
sys_clk = 0; |
|||
rst_n = 0; |
|||
#100; |
|||
rst_n = 1; |
|||
timecode_in = 0; |
|||
one_timecode_end = 0; |
|||
#100; |
|||
|
|||
// |
|||
// timecode_generator(79'h1234_4321_1234_4321_CFFB); |
|||
// timecode_generator(79'h0000_0000_0000_0000_CFFB); |
|||
timecode_generator(80'hBFFC_0000_0000_0000_0000); |
|||
// timecode_generator(79'b1011_1111_1111_1100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000); |
|||
//FFFF |
|||
//4444 |
|||
//16+16+16+16+16 |
|||
// 32 32 80 |
|||
// |
|||
|
|||
// timecode_generator(79'hBFFC_0000_0000_0000_0000); |
|||
// timecode_generator(79'hBFFC_0000_0000_0000_0000); |
|||
one_timecode_end = 1; |
|||
#1000000; |
|||
timecode_generator(80'hBFFC_0102_0304_0506_0102); |
|||
|
|||
#100000000; |
|||
$stop; |
|||
end |
|||
always #5 sys_clk = ~sys_clk; // 50MHZ时钟 |
|||
endmodule |
Write
Preview
Loading…
Cancel
Save
Reference in new issue