基于FPGA的1080P 60Hz BT1120接口调试过程记录
这个BT1120接口是在1080P 60Hz的视频中验证的,其它频率的视频使用时要修改对应的参数。另外由于接口代码里面例化了一个深度位512的FIFO(quartus),所以在做仿真测试时需要quartus和modelsim联合仿真。
bt1120接口最重要的部分是结束码和起始码(FF 00 00 XYZ)
前面3字节的FF 00 00 是固定不变的,最后一字节需要根据F V H来编码,当FVH确定时P3 P2 P1 P0也确定了。使用8bit的数据位宽时保留高8位,舍去低2位。
整理后的接口
接口代码
/* 定时基准码 <0xff 0x00 0x00 xxx>* 其中xxx为如下的取值范围:* 1 0 1 0 1 0 1 1 0 0 0xab(帧消隐期间,SAV)* 1 0 1 1 0 1 1 0 0 0 0xb6(帧消隐期间,EAV)* 1 0 0 0 0 0 0 0 0 0 0x80(视频有效区时间,SAV)* 1 0 0 1 1 1 0 1 0 0 0x9d(视频有效区时间,EAV)*/`timescale 1ns / 1ps
module ycbcr422_to_bt1120(input rst_n,input clk ,input data_de,input hsync,input vsync,input [15:0] ycbcr, output bt1120_pclk,output reg [15:0] bt1120_ycbcr);localparam BLANKING = 4'd0; //消隐阶段 //SAVlocalparam CODE_SAV1 = 4'd1; //数据开始码阶段localparam CODE_SAV2 = 4'd2;localparam CODE_SAV3 = 4'd3;localparam CODE_SAV4 = 4'd4;//EAVlocalparam CODE_EAV1 = 4'd5; //数据结束码阶段localparam CODE_EAV2 = 4'd6;localparam CODE_EAV3 = 4'd7;localparam CODE_EAV4 = 4'd8;localparam VAILD_VIDEO = 4'd9; //数据有效阶段//在行场消隐区填充STUFFlocalparam STUFF = 16'h8010;localparam BSAV = 8'hab;localparam BEAV = 8'hb6;localparam VSAV = 8'h80;localparam VEAV = 8'h9d;//1080p 60hz
localparam WIDTH_TOTAL = 12'd2200 ; //一行的宽度
localparam HEIGHT_TOTAL= 12'd1125 ; //一帧的高度
localparam VIDEO_BEFORE_BLANK_NUM = 6'd41 ; //一帧开始前的帧消隐行数
localparam VIDEO_AFTER_BLANK_NUM = 3'd4 ; //一帧结束后的帧消隐行数
localparam BLANK_NUM = 12'd280 ;wire full ;
reg rd_en ;
wire[15:0] rd_data ;
wire empty ;reg [3:0] state_c ;
reg [3:0] state_n ;
wire blank2sav ;
wire video2eav ;reg data_de0 ;
reg hsync0 ;
reg vsync0 ;
reg [15:0] ycbcr0 ;
reg data_de1 ;
reg hsync1 ;
reg vsync1 ;
reg [15:0] ycbcr1 ;
wire v_pos ;reg [11:0] cnt_h ;
reg [11:0] cnt_v ; wire[7:0] Lumi ;
wire[7:0] cbcr ;assign bt1120_pclk = clk ;yc2bt_fifo yc2bt_fifo_inst0
(.clock (clk ),.data (ycbcr1 ),.wrreq (data_de1),.full (full ),.rdreq (rd_en ),.q (rd_data ),.empty (empty )
);always@(posedge clk or negedge rst_n)beginif(!rst_n)beginstate_c <= BLANKING;endelse beginstate_c <= state_n;end
endalways@(*)begincase(state_c)BLANKING:beginif(blank2sav)beginstate_n = CODE_SAV1;endelse beginstate_n = state_c;endendCODE_SAV1:beginstate_n = CODE_SAV2;endCODE_SAV2:beginstate_n = CODE_SAV3;endCODE_SAV3:beginstate_n = CODE_SAV4;endCODE_SAV4:beginstate_n = VAILD_VIDEO;endVAILD_VIDEO:beginif(video2eav)beginstate_n = CODE_EAV1;endelse beginstate_n = state_c;endendCODE_EAV1:beginstate_n = CODE_EAV2;endCODE_EAV2:beginstate_n = CODE_EAV3;endCODE_EAV3:beginstate_n = CODE_EAV4;endCODE_EAV4:beginstate_n = BLANKING;end default:beginstate_n = BLANKING;endendcase
endassign blank2sav = state_c==BLANKING && cnt_h==12'd275;
assign video2eav = state_c==VAILD_VIDEO && cnt_h==12'd2199;//输入打拍
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begindata_de0 <= 1'b0 ;hsync0 <= 1'b0 ;vsync0 <= 1'b0 ;ycbcr0 <= 16'b0 ;endelse begindata_de0 <= data_de ;hsync0 <= hsync ;vsync0 <= vsync ;ycbcr0 <= ycbcr ;data_de1 <= data_de0 ;hsync1 <= hsync0 ;vsync1 <= vsync0 ;ycbcr1 <= ycbcr0 ;end
end//获取场信号上升沿
assign v_pos = !vsync1 && vsync0 ;//一行计数器
always @(posedge clk )beginif(v_pos || cnt_h == WIDTH_TOTAL-1)cnt_h <= 12'b0;else cnt_h <= cnt_h + 1;
end//一帧计数器
always @(posedge clk )beginif(v_pos)cnt_v <= 12'b0;else if(cnt_h == WIDTH_TOTAL-1)beginif(cnt_v == HEIGHT_TOTAL-1)cnt_v <= 12'b0;elsecnt_v <= cnt_v + 1;end
end //出数据
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginbt1120_ycbcr <= STUFF ;endelse begin case(state_c)BLANKING:begin bt1120_ycbcr<= STUFF ; endCODE_SAV1:begin bt1120_ycbcr<= 16'hffff ; endCODE_SAV2:begin bt1120_ycbcr<= 16'h0 ; end CODE_SAV3:begin bt1120_ycbcr<= 16'h0 ; end CODE_SAV4:beginif(cnt_v<12'd41 ||(cnt_v >= 12'd1121 && cnt_v < 12'd1125)) bt1120_ycbcr<= 16'habab ;else if(cnt_v>=12'd41 && cnt_v<12'd1121)bt1120_ycbcr<= 16'h8080 ; endVAILD_VIDEO:begin bt1120_ycbcr<= rd_data ; endCODE_EAV1:beginbt1120_ycbcr <= 16'hffff;endCODE_EAV2:beginbt1120_ycbcr <= 16'h0;endCODE_EAV3:beginbt1120_ycbcr <= 16'h0;endCODE_EAV4:beginif(cnt_v<12'd41 ||(cnt_v >= 12'd1121 && cnt_v < 12'd1125)) bt1120_ycbcr<= 16'hb6b6 ;else if(cnt_v>=12'd41 && cnt_v<12'd1121)bt1120_ycbcr<= 16'h9d9d ;end endcase end
endassign Lumi = bt1120_ycbcr[15:8] ;
assign cbcr = bt1120_ycbcr[7:0] ;
//read en
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginrd_en <= 1'b0 ;endelse if(cnt_v>=12'd41 && cnt_v < 12'd1121 )beginif(cnt_h>=12'd279 && cnt_h<12'd2200)rd_en <= 1'b1 ;elserd_en <= 1'b0 ;endelse beginrd_en <= 1'b0 ;end
endendmodule
测试文件
`timescale 1 ns/1psmodule tb_bt1120();reg clk ;
reg rst_n;
wire[15:0] ycrcb;
reg de ;
reg vsync;
reg hsync;
reg[11:0] cnt_h;
reg[11:0] cnt_v;
reg[7:0] lumi ;
reg[7:0] cbcr ;//uut的输出信号
wire bt1120_clk;
wire[15:0] bt1120_data;//时钟周期,单位为ns,可在此修改时钟周期。
parameter CYCLE = 7;//复位时间,此时表示复位3个时钟周期的时间。
parameter RST_TIME = 20 ;ycbcr422_to_bt1120 u_ycbcr422_to_bt1120(.rst_n (rst_n ), //input .clk (clk ), //input .data_de (de ), //input [15:0] .hsync (hsync ), //input .vsync (vsync ), //input .ycbcr (ycrcb ), //input //bt.1120接口.bt1120_pclk (bt1120_clk ) , //output .bt1120_ycbcr(bt1120_data) //output reg[15:0] );
//1080P 60Hz
parameter h_total = 12'd2200;
parameter hsync_pw = 6'd44 ; //行消隐脉冲宽度,以时钟为单位parameter v_total = 12'd1125;
parameter vsync_pw = 3'd5 ; //行消隐脉冲宽度,以行为单位parameter data_f_enabel = 6'd42 ; //有效数据的第一行,以行为单位
parameter data_e_enabel = 12'd1120; //有效数据的最后一行,以行为单位parameter data_de_start = 8'd192 ; //数据有效开始,以时钟为单位
parameter data_de_end = 12'd2112; //数据有效结束,以时钟为单位//生成本地时钟50M
initial beginclk = 0;forever#(CYCLE/2)clk=~clk;
end//产生复位信号
initial beginrst_n = 1;#2;rst_n = 0;#(CYCLE*RST_TIME);rst_n = 1;
end//一行数据的计数器
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begincnt_h <= 12'b0 ;endelse beginif(cnt_h == h_total-1)cnt_h <= 12'b0 ;elsecnt_h <= cnt_h + 1 ;end
end//一帧数据的计数器,1080P 60hz的一帧数据共有1125行
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begincnt_v <= 12'b0 ;endelse if(cnt_h == h_total-1)beginif(cnt_v == v_total-1)cnt_v <= 12'b0 ;elsecnt_v <= cnt_v + 1 ;end
end//产生行信号
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginhsync <= 1'b0 ;endelse if(cnt_h < hsync_pw )beginhsync <= 1'b1 ;endelse beginhsync <= 1'b0 ;end
end//产生场信号
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginvsync <= 1'b0 ;endelse if(cnt_v < vsync_pw )beginvsync <= 1'b1 ;endelse beginvsync <= 1'b0 ;end
end//产生数据有效信号
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginde <= 1'b0 ;lumi <= 8'b0;cbcr <= 8'b0;endelse if(cnt_v >= data_f_enabel-1 && cnt_v <= data_e_enabel)beginif(cnt_h >= data_de_start-1 && cnt_h < data_de_end-1 )beginde <= 1'b1 ;lumi <= lumi+1;cbcr <= cbcr+1;endelse beginde <= 1'b0 ;lumi <= 8'b0;cbcr <= 8'b0;endend
endassign ycrcb = {lumi,cbcr} ;endmodule
基于FPGA的1080P 60Hz BT1120接口调试过程记录相关推荐
- 一种基于FPGA 的1080p 高清多摄像头全景视频拼接的泊车(机)
< > 一种基于FPGA 的1080p 高清多摄像头全景视频拼接的泊车(机)实时影像系统 一.本发明要解决的实际问题 1. 汽车左右反光镜及后视镜的视角有限,导致车身周围存在盲区,在特殊驾 ...
- 基于FPGA的FOC电流采样Bug调试记录
#基于FPGA的FOC电流采样Bug调试记录 博主在调试FOC闭环控制中遇到了一个bug,冥思苦想两三天,最终一步步地调试时序,最终找到了bug,在调试过程中学会了debug的思想,也明白了调试过程中 ...
- 腾讯在线教育互动课堂——Demo调试过程记录
官方文档地址:https://cloud.tencent.com/document/product/680/17888 "Demo调试"不像集成使用,不需要完全按照文档一步步处理, ...
- Proteus仿真stm32和51单片机,串口通信调试过程记录
前言 本文所用Proteus版本为8.10,主要内容为在Proteus中仿真stm32和51单片机进行串口通信,记录了仿真过程中遇到的问题和解决办法. 这里要注意的是,在Proteus中 ...
- SGM58031的IIC接口调试过程
圣邦微电子推出的SGM58031是具有16位分辨率的精密模数转换器(ADC),设计具有高精度.低功耗和易于实现的特点,具有片内基准电压源和振荡器,数据通过兼容I2C的串行接口进行传输. 先来看看SGM ...
- 基于FPGA的高速ADC9XXX系列的产品研发记录与心得----系列二(玩FPGA玩到最后还是玩时钟)
当板子回来之后我们的数据二通道还是存在bug,通过测试发现,还是在测试模式下面,adC的输出数据没有问题,但在接收的那边还是存在如下图的问题,通过电源AVDD和DVDD的查看发现,没有问题啊!!! 如 ...
- PCIE 调试过程记录
遇到的问题 PCIE link不稳定 配置空间读写正常,Memory mapping空间读写异常 缘由 之前对PCIE的认识一直停留在概念的阶段,只知道是一个高速通讯协议,主要用于板内.板间的高速BU ...
- pixhawk4连接PX4 Flow光流传感器调试过程记录
主控型号:Pixhawk4 光流型号:PX4 FLow V1.3 地面站:QGroundControl 1.拔掉PX4 Flow连接Pixhawk4的连接线,用USB连接PX4 Flow,打开QGC地 ...
- ubuntu加载4G模块驱动的调试过程记录
一个工业平板电脑,原本安装的是win7系统,希望改用ubuntu系统.其他的驱动都好说,关键是有个4G模块,平板电脑厂家使用的是一个小品牌的,ubuntu内部没有集成驱动,需要自己编译驱动.这个对li ...
- 纯小白新人菜鸟第一次unity VR项目与matlab联动调试过程记录超详细版本2023.3.12
本人是个超级菜鸟,因为项目需要用到unity.matlab并且实现两者联动,才刚开始接触Unity.Matlab,以前只有一点C/C++和Java基础(好几年前学的,只会加减乘除.连dll是什么都不懂 ...
最新文章
- mysql dba系统学习(18)mysql主从复制的实现 mysql dba系统学习(19)配置mysql+lvs+keeplived实现Mysql读操作的负载均衡
- (SpringMVC)Controller返回JSON数据
- 那些牛逼的数据分析师,SQL用的到底有多溜
- python内置函数open的解释_在python的内置open()函数中缓冲的用途是什么?
- anaconda base环境_Mac系统下借助Anaconda为jupyter notebook添加多个python内核及相关操作...
- word手写字体以假乱真_轻松制作个人“电子版手写签名”
- java ajax异步验证,【求助】真的不会做了。。关于AJAX异步验证的问题。。
- Javascript数据类型,类型转换
- 阅读underscore源码笔记
- 黑马程序员传智播客迭代器和循环生成fibonacci数列
- C语言例题-打印日历
- 机智云智慧烟感物联网解决方案
- 【机器学习】 吴恩达机器学习作业 ex1 python实现+Matlab实现
- java-用for循环打印大写字母(部分简单大写字母)
- 基于R语言进行K折交叉验证
- Chapter 12 设计概念
- mysql cbrt函数_ES6 数值的扩展
- 十个突出问题整改追踪:智慧城市建设滞后
- “感动中国”2012年度人物颁奖词
- 群辉 Docker-x64-17.05.0-0400.spk,用来群晖洗白,安装ddsm使用