当前位置:网站首页>基于FPGA的1080P 60Hz BT1120接口调试过程记录
基于FPGA的1080P 60Hz BT1120接口调试过程记录
2022-07-25 19:00:00 【丹霞山下的FPGA少年】
这个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; //消隐阶段 //SAV localparam CODE_SAV1 = 4'd1; //数据开始码阶段
localparam CODE_SAV2 = 4'd2; localparam CODE_SAV3 = 4'd3;
localparam CODE_SAV4 = 4'd4; //EAV localparam CODE_EAV1 = 4'd5; //数据结束码阶段
localparam CODE_EAV2 = 4'd6; localparam CODE_EAV3 = 4'd7;
localparam CODE_EAV4 = 4'd8; localparam VAILD_VIDEO = 4'd9; //数据有效阶段
//在行场消隐区填充STUFF
localparam 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 )
);
[email protected](posedge clk or negedge rst_n)begin
if(!rst_n)begin
state_c <= BLANKING;
end
else begin
state_c <= state_n;
end
end
[email protected](*)begin
case(state_c)
BLANKING:begin
if(blank2sav)begin
state_n = CODE_SAV1;
end
else begin
state_n = state_c;
end
end
CODE_SAV1:begin
state_n = CODE_SAV2;
end
CODE_SAV2:begin
state_n = CODE_SAV3;
end
CODE_SAV3:begin
state_n = CODE_SAV4;
end
CODE_SAV4:begin
state_n = VAILD_VIDEO;
end
VAILD_VIDEO:begin
if(video2eav)begin
state_n = CODE_EAV1;
end
else begin
state_n = state_c;
end
end
CODE_EAV1:begin
state_n = CODE_EAV2;
end
CODE_EAV2:begin
state_n = CODE_EAV3;
end
CODE_EAV3:begin
state_n = CODE_EAV4;
end
CODE_EAV4:begin
state_n = BLANKING;
end
default:begin
state_n = BLANKING;
end
endcase
end
assign 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)begin
if(rst_n==1'b0)begin data_de0 <= 1'b0 ;
hsync0 <= 1'b0 ; vsync0 <= 1'b0 ;
ycbcr0 <= 16'b0 ; end else begin data_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 )begin if(v_pos || cnt_h == WIDTH_TOTAL-1) cnt_h <= 12'b0;
else
cnt_h <= cnt_h + 1;
end
//一帧计数器
always @(posedge clk )begin
if(v_pos)
cnt_v <= 12'b0; else if(cnt_h == WIDTH_TOTAL-1)begin if(cnt_v == HEIGHT_TOTAL-1) cnt_v <= 12'b0;
else
cnt_v <= cnt_v + 1;
end
end
//出数据
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin bt1120_ycbcr <= STUFF ; end else begin case(state_c) BLANKING:begin bt1120_ycbcr<= STUFF ; end CODE_SAV1:begin bt1120_ycbcr<= 16'hffff ;
end
CODE_SAV2:begin
bt1120_ycbcr<= 16'h0 ; end CODE_SAV3:begin bt1120_ycbcr<= 16'h0 ;
end
CODE_SAV4:begin
if(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 ; end VAILD_VIDEO:begin bt1120_ycbcr<= rd_data ; end CODE_EAV1:begin bt1120_ycbcr <= 16'hffff;
end
CODE_EAV2:begin
bt1120_ycbcr <= 16'h0; end CODE_EAV3:begin bt1120_ycbcr <= 16'h0;
end
CODE_EAV4:begin
if(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 end assign Lumi = bt1120_ycbcr[15:8] ; assign cbcr = bt1120_ycbcr[7:0] ; //read en always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin
rd_en <= 1'b0 ; end else if(cnt_v>=12'd41 && cnt_v < 12'd1121 )begin if(cnt_h>=12'd279 && cnt_h<12'd2200) rd_en <= 1'b1 ;
else
rd_en <= 1'b0 ; end else begin rd_en <= 1'b0 ;
end
end
endmodule
测试文件
`timescale 1 ns/1ps
module 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 begin
clk = 0;
forever
#(CYCLE/2)
clk=~clk;
end
//产生复位信号
initial begin
rst_n = 1;
#2;
rst_n = 0;
#(CYCLE*RST_TIME);
rst_n = 1;
end
//一行数据的计数器
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin cnt_h <= 12'b0 ;
end
else begin
if(cnt_h == h_total-1)
cnt_h <= 12'b0 ; else cnt_h <= cnt_h + 1 ; end end //一帧数据的计数器,1080P 60hz的一帧数据共有1125行 always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin
cnt_v <= 12'b0 ; end else if(cnt_h == h_total-1)begin if(cnt_v == v_total-1) cnt_v <= 12'b0 ;
else
cnt_v <= cnt_v + 1 ;
end
end
//产生行信号
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin hsync <= 1'b0 ;
end
else if(cnt_h < hsync_pw )begin
hsync <= 1'b1 ; end else begin hsync <= 1'b0 ;
end
end
//产生场信号
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin vsync <= 1'b0 ;
end
else if(cnt_v < vsync_pw )begin
vsync <= 1'b1 ; end else begin vsync <= 1'b0 ;
end
end
//产生数据有效信号
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin de <= 1'b0 ;
lumi <= 8'b0; cbcr <= 8'b0;
end
else if(cnt_v >= data_f_enabel-1 && cnt_v <= data_e_enabel)begin
if(cnt_h >= data_de_start-1 && cnt_h < data_de_end-1 )begin
de <= 1'b1 ; lumi <= lumi+1; cbcr <= cbcr+1; end else begin de <= 1'b0 ;
lumi <= 8'b0; cbcr <= 8'b0;
end
end
end
assign ycrcb = {
lumi,cbcr} ;
endmodule
边栏推荐
- Twitter acquired a public opinion war, which was turned into a child quarrel by musk
- 一个免费的镜像下载仓库网站
- 600000 pieces of data are made from March 1 to March 31. Videodate requires starting time from 00:00 to 24:00 on March 1 to 31, which is only for notes
- 2022年IAA行业品类发展洞察系列报告·第二期
- 软件测试流程(思维导图)
- ES6通过代理器(Proxy)与反射(Reflect)实现观察者模式
- A free image download warehouse website
- jmeter性能测试实战视频(常用性能测试工具有哪些)
- 进程间的通信(管道通信)
- 无惧高温暴雨,有孚网络如何保您无忧?
猜你喜欢

What is hpapaas platform?

Baklib:制作优秀的产品说明手册

常用的开发软件下载地址

给生活加点惊喜,做创意生活的原型设计师丨编程挑战赛 x 选手分享
![[help center] provide your customers with the core options of self-service](/img/66/5a927e3bdcc165b78d4a9dee324871.png)
[help center] provide your customers with the core options of self-service

Share six practical applet plug-ins

乐理基础 调式

分享六个实用的小程序插件

Pixel2Mesh从单个RGB图像生成三维网格ECCV2018

Huawei switch system software upgrade and security vulnerability repair tutorial
随机推荐
MySQL sub query (selected 20 sub query exercises)
Fruit chain "siege": it's a journey of sweetness and bitterness next to apples
[encryption weekly] has the encryption market recovered? The cold winter has not thawed yet! Check the major events in the encryption market last week!
「Wdsr-3」蓬莱药局 题解
蓝牙协议详解(蓝牙是什么)
果链“围城”:傍上苹果,是一场甜蜜与苦楚交错的旅途
无惧高温暴雨,有孚网络如何保您无忧?
With a financing of 200million yuan, the former online bookstore is now closed nationwide, with only 3 stores left in 60 stores
JMeter performance test actual video (what are the common performance test tools)
C 调的满级和玄
Youth, oh, youth
The bank's wealth management subsidiary accumulates power to distribute a shares; The rectification of cash management financial products was accelerated
Typescript对象代理器Proxy使用
Circulaindicator component, which makes the indicator style more diversified
Yyds dry inventory interview must brush top101: reverse linked list
Korean AI team plagiarizes shock academia! One tutor with 51 students, or plagiarism recidivist
MySQL子查询篇(精选20道子查询练习题)
一个免费的镜像下载仓库网站
接口自动化测试平台FasterRunner系列(三)- 操作示例
ES6 implements the observer mode through proxy and reflection