看图写代码---看图写代码 阅读<<Audio/Video Connectivity Solutions for Virtex-II Pro and Virtex-4 FPGAs >>
Posted on 2017-07-25 18:40 沉默改良者 阅读(391) 评论(0) 编辑 收藏 举报看图写代码
阅读<<Audio/Video Connectivity Solutions for Virtex-II Pro and Virtex-4 FPGAs >>
1.SDI Block Diagram and SD-SDI Section Chapters
2.XYZ Word Format for the 4:4:4:4 TRS Symbol
端口定义:
module trs_detect ( // inputs clk, // clock input ce, // clock enable rst, // async reset input vid_in, // video input // outputs vid_out, // delayed and clipped video output rx_trs, // asserted during first word of TRS symbol rx_eav, // asserted during first word of an EAV symbol rx_sav, // asserted during first word of an SAV symbol rx_f, // field bit from last received TRS symbol rx_v, // vertical blanking interval bit from last TRS symbol rx_h, // horizontal blanking interval bit from last TRS symbol rx_xyz, // asserted during TRS XYZ word rx_xyz_err, // XYZ error flag for non-4444 standards rx_xyz_err_4444,// XYZ error flag for 4444 standards rx_anc, // asserted during first word of ADF rx_edh // asserted during first word of ADF if it is an EDH packet );
以下代码的作用是对输入数据(vid_in)进行解码:
1.寄存器锁存vid_in数据:
// // in_reg // // The input register loads the value on the vid_in port. // always @ (posedge clk or posedge rst) if (rst) in_reg <= 0; else if (ce) //时钟使能 in_reg <= vid_in; //接收数据
2.检测是否有输入的数据全为1即3FF,或者全为0即000:
all_ones_in 和 all_zeros_in采用的是组合逻辑
// // all ones and all zeros detectors // // This logic determines if the input video word is all ones or all zeros. To // provide compatibility with 8-bit video equipment, the LS two bits are // ignored. // assign all_ones_in = &in_reg[9:2]; //检测输入的图像数据是否全为0或者1 assign all_zeros_in = ~|in_reg[9:2];
3.将接收到的视频数据,和生成的all_ones_in , all_zeros_in信号存入寄存器 pipe1
// // pipe1 // // The pipe1 register holds the inut video and the outputs of the all zeros // and all ones detectors. // always @ (posedge clk or posedge rst) //锁存接收到的数据 if (rst) begin pipe1_vid <= 0; pipe1_ones <= 1'b0; pipe1_zeros <= 1'b0; end else if (ce) begin pipe1_vid <= in_reg; pipe1_ones <= all_ones_in; pipe1_zeros <= all_zeros_in; end
4.将pipe1里面的数据存入pipe2寄存器,这就相当于把pipe1延时一个时钟周期:
// // pipe2_reg // // The pipe2 register delays the contents of the pipe1 register for one more // clock cycle. // always @ (posedge clk or posedge rst) //将pipe1延时一个时钟周期 if (rst) begin pipe2_vid <= 0; pipe2_ones <= 1'b0; pipe2_zeros <= 1'b0; end else if (ce) begin pipe2_vid <= pipe1_vid; pipe2_ones <= pipe1_ones; pipe2_zeros <= pipe1_zeros; end
5.现在我们可以认为,pipe2寄存器里面传入的是最先传入的第一个视频数据,pipe1里面传入的是紧跟着的第二个视频数据,all_zeros_in显示的是当前传入的视频数据的状态。此段代码的功能是对三个连续的视频数据进行检测,是否有3ff,000,000 和 000,000,3ff这样连续的三个数据。
// // TRS & ANC detector // // The trs signal when the sequence 3ff, 000, 000 is stored in the pipe2, pipe1, // and in_reg registers, respectively. The anc signal is asserted when these // same registers hold the sequence 000, 3ff, 3ff. // assign trs = all_zeros_in & pipe1_zeros & pipe2_ones; //原来如此,3ff,000,000检测 assign anc = all_ones_in & pipe1_ones & pipe2_zeros; //000,3ff,3ff 检测 assign eav = trs & vid_in[6]; //当检测到了trs之后,下一个视频数据就是xyz的信息,其中的第6位为H H =1 assign sav = trs & ~vid_in[6]; // H = 0
当检测到3ff,000,000 时,trs变为高电平,当检测到000,000,3ff时,anc变为高电平,当检测到TRS时候,我们再解码EAV 和 SAV。
参考BT.656的标准:
我们可以知道,SAV 和 EAV 是由TRS symbol 中的第6位H的值来确定的,因此有了:eav 和 sav 信号的逻辑产生。
6.产生 f, v, h信号
// // f, v, and h flag generation // assign f = trs ? vid_in[8] : out_reg_f; assign v = trs ? vid_in[7] : out_reg_v; assign h = trs ? vid_in[6] : out_reg_h;
当检测到trs信号时,f,v,h的信号分别是当前传入视频数据的第8,7,6位,当没有检测到trs信号时,返回的是输出寄存器里面的值,即上一次检测到trs的时候,f,v,h的状态
7.关于XYZ信号的检测
首先:trs将值传递给out_reg_trs需要一个时钟周期。
// // output reg // // The output register holds the the output video data and various flags. // always @ (posedge clk or posedge rst) if (rst) begin out_reg_vid <= 0; out_reg_trs <= 1'b0; out_reg_eav <= 1'b0; out_reg_sav <= 1'b0; out_reg_anc <= 1'b0; out_reg_edh <= 1'b0; out_reg_xyz <= 1'b0; out_reg_xyz_err <= 1'b0; out_reg_xyz_err_4444 <= 1'b0; out_reg_f <= 0; out_reg_v <= 0; out_reg_h <= 0; end else if (ce) begin out_reg_vid <= pipe2_vid; out_reg_trs <= trs; out_reg_eav <= eav; out_reg_sav <= sav; out_reg_anc <= anc; out_reg_edh <= anc & edh_in; out_reg_xyz <= xyz; out_reg_xyz_err <= xyz_err; out_reg_xyz_err_4444 <= xyz_err_4444; out_reg_f <= f; out_reg_v <= v; out_reg_h <= h; end
然后:out_reg_trs传入trs_delay[0]信号需要一个时钟周期
// // trs_delay register // // Used to assert the xyz signal when pipe2 contains the XYZ word of a TRS // symbol. always @ (posedge clk or posedge rst) if (rst) trs_delay <= 2'b00; else if (ce) trs_delay <= {trs_delay[0], out_reg_trs};
将out_reg_trs的值传递到trs_delay[1]又需要一个时钟周期
经过三个时钟周期,XYZ的值已经存储在了pipe2寄存器上面,因此才有了如下代码:对xyz中的数据进行校验。
// // XYZ and XYZ error logic // // The xyz signal is asserted when the pipe2 register holds the XYZ word of a // TRS symbol. The xyz_err signal is asserted if an error is detected in the // format of the XYZ word stored in pipe2. This signal is not valid for the // 4444 component digital video formats. The xyz_err_4444 signal is asserted // for XYZ word format errors. // assign xyz = trs_delay[1]; assign xyz_err = xyz & ((pipe2_vid[5] ^ pipe2_vid[7] ^ pipe2_vid[6]) | // P3 = V ^ H (pipe2_vid[4] ^ pipe2_vid[8] ^ pipe2_vid[6]) | // P2 = F ^ H (pipe2_vid[3] ^ pipe2_vid[8] ^ pipe2_vid[7]) | // P1 = F ^ V (pipe2_vid[2] ^ pipe2_vid[8] ^ pipe2_vid[7] ^ pipe2_vid[6]) | // P0 = F ^ V ^ H ~pipe2_vid[9]); assign xyz_err_4444 = xyz & ((pipe2_vid[4] ^ pipe2_vid[8] ^ pipe2_vid[7] ^ pipe2_vid[6]) | // P4 = F ^ V ^ H (pipe2_vid[3] ^ pipe2_vid[8] ^ pipe2_vid[7] ^ pipe2_vid[5]) | // P3 = F ^ V ^ S (pipe2_vid[2] ^ pipe2_vid[7] ^ pipe2_vid[6] ^ pipe2_vid[5]) | // P2 = V ^ H ^ S (pipe2_vid[1] ^ pipe2_vid[8] ^ pipe2_vid[6] ^ pipe2_vid[5]) | // P1 = F ^ H ^ S ~pipe2_vid[9]);