FPGA实现BT.1120编码
研究了两天的BT1120规范,以及CEA-861-D视频时序,找到了一些对应关系(见我另外一篇文章《视频时序与BT1120的关系》)。于是写了如下的verilog代码,可对接sii9134芯片的行场内嵌方式,其中sii9134配置C代码如下:
void sii9134_init(void)
{
u8 u8Data = 0;
I2C_WriteByte(0x05, 0x08, 0x72); //value reg_addr device_addr
I2C_ReadByte(&u8Data, sizeof(u8), 0x33, 0x72);
I2C_WriteByte(u8Data & 0x8f, 0x33, 0x72);
I2C_WriteByte(0x6e, 0x40, 0x72);
I2C_WriteByte(0x28, 0x44, 0x72);
I2C_WriteByte(0x00, 0x45, 0x72);
I2C_WriteByte(0x05, 0x46, 0x72);
I2C_WriteByte(0x05, 0x47, 0x72);
I2C_WriteByte(0x30, 0x48, 0x72);
I2C_WriteByte(0x3d, 0x4a, 0x72);
}
FPGA实验板使用黑金的AV6045开发板。
FPGA端的bt1120 verilog代码如下(行场同步信号hsync和vsync为高电平有效):
另外,如果发现像素数据为0xff或0x00则需要替换为0xfe和0x01,防止对端误判。(本文没有做这一步)
/**
* author : mkelehk@gmail.com
* time : 2017/8/28
* function : ycbcr4:2:2 embed_hs_vs encoder module, compatible bt.1120
*
* 定时基准码 <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 / 100ps
module embed_hs_vs_enc(
input rst,
input yc422_pclk_i,
input [15:0] yc422_data_i,
input yc422_de_i,
input yc422_vs_i,
input yc422_hs_i,
//--------------------------------------------------------
//视频时序参数,由CPU 通过i2c配置得到
input [11:0] width_i, // l
input [11:0] height_i, //
input [11:0] hs_rising_to_de_i,
input [11:0] hor_total_g_i,
input [11:0] vs_rising_to_de_i, //L2
input [11:0] ver_total_g_i, //L6
//----------------------------------------------------------
input video_pararm_enable_i,
//----------------------------------------------------------
//bt.1120接口
output embed_hs_vs_pclk_o,
output reg[15:0] embed_hs_vs_yc422_o
);
//状态机状态
localparam INVAILD_BLANKING = 4'd0;
localparam VAILD_VIDEO = 4'd1;
localparam SYNC1_SAV = 4'd2;
localparam SYNC2_SAV = 4'd3;
localparam SYNC3_SAV = 4'd4;
localparam SYNC1_EAV = 4'd5;
localparam SYNC2_EAV = 4'd6;
localparam SYNC3_EAV = 4'd7;
localparam SAV_BKANKING = 4'd8;
localparam EAV_BKANKING = 4'd9;
localparam SAV_VIDEO = 4'd10;
localparam EAV_VIDEO = 4'd11;
//在行场消隐区填充STUFF
localparam STUFF = 16'h8010;
wire hs_rising; //rising or falling
wire vs_rising;
reg [11:0] vs_cnt;//场计数器
reg [11:0] hs_cnt;//行计数器
//复位信号要处理好,否则以下寄存器值未初始化
reg [11:0] width_g;
reg [11:0] height_g;
reg [11:0] hs_rising_to_de_g;
reg [11:0] hor_total_g;
reg [11:0] vs_rising_to_de_g;
reg [11:0] ver_total_g;
reg [3:0]state_cs;//当前状态 需注意寄存器变量的位宽,防止溢出
reg [3:0]state_ns;//下一个状态
//对信号进行延时操作,打1拍
//reg[15:0] yc422_data_d1;
reg yc422_de_d1;
reg yc422_vs_d1;
reg yc422_hs_d1;
always @(posedge yc422_pclk_i)
begin
if(rst) begin
//yc422_data_d1 <= 16'h00;
yc422_de_d1 <= 1'b0;
yc422_vs_d1 <= 1'b0;
yc422_hs_d1 <= 1'b0;
end else begin
//yc422_data_d1 <= yc422_data_i;
yc422_de_d1 <= yc422_de_i;
yc422_vs_d1 <= yc422_vs_i;
yc422_hs_d1 <= yc422_hs_i;
end
end
assign embed_hs_vs_pclk_o = yc422_pclk_i;
assign hs_rising = ~yc422_hs_d1 & yc422_hs_i;
assign vs_rising = ~yc422_vs_d1 & yc422_vs_i;
always @(posedge yc422_pclk_i)
begin
if(rst) begin
width_g <= 12'd1920;
height_g <= 12'd1080;
hs_rising_to_de_g <= 12'd192;
hor_total_g <= 12'd2200;
vs_rising_to_de_g <= 12'd41;
ver_total_g <= 12'd1125;
end else if(video_pararm_enable_i)begin
width_g <= width_i;
height_g <= height_i;
hs_rising_to_de_g <= hs_rising_to_de_i;
hor_total_g <= hor_total_g_i;
vs_rising_to_de_g <= vs_rising_to_de_i;
ver_total_g <= ver_total_g_i;
end
end
//行计数
always @(posedge yc422_pclk_i)
begin
if(rst)
hs_cnt <= 0;
else if(hs_rising || video_pararm_enable_i)
hs_cnt <= 0;
else if(hs_cnt == hor_total_g - 1'b1)
hs_cnt <= 0;
else
hs_cnt <= hs_cnt + 1'b1;
end
//帧计数
always @(posedge yc422_pclk_i)
begin
if(rst)
vs_cnt <= 0;
else if(vs_rising || video_pararm_enable_i)
vs_cnt <= 0;
else if(hs_cnt == hor_total_g - 1'b1)
if(vs_cnt == ver_total_g - 1'b1)
vs_cnt <= 0;
else
vs_cnt <= vs_cnt + 1'b1;
else
vs_cnt <= vs_cnt;
end
always @(posedge yc422_pclk_i)
begin
if(rst)
state_cs <= INVAILD_BLANKING;
else
state_cs <= state_ns;
end
always @(*)
begin
case(state_cs)
INVAILD_BLANKING :
begin
if(hs_cnt == hs_rising_to_de_g - 3'd6) //SAV 提前4个时钟,因为SAV和EAV要包含4个时钟周期,并且补偿state_cs和第三段带来的2拍延时
state_ns = SYNC1_SAV;
else if(hs_cnt == hs_rising_to_de_g + width_g - 3'd2) //EAV 不需要提前4个时钟,但需要补偿state_cs和第三段带来的2拍延时
state_ns = SYNC1_EAV;
else
state_ns = INVAILD_BLANKING;
end
//SAV部分
SYNC1_SAV : state_ns = SYNC2_SAV;
SYNC2_SAV : state_ns = SYNC3_SAV;
SYNC3_SAV :
if((vs_cnt >= vs_rising_to_de_g - 1'b1) && (vs_cnt <= height_g + vs_rising_to_de_g - 1'b1))//VILD_VIDEO
state_ns = SAV_VIDEO;
else
state_ns = SAV_BKANKING;
//EAV部分
SYNC1_EAV : state_ns = SYNC2_EAV;
SYNC2_EAV : state_ns = SYNC3_EAV;
SYNC3_EAV :
if((vs_cnt >= vs_rising_to_de_g - 1'b1) && (vs_cnt <= height_g + vs_rising_to_de_g - 1'b1))//VILD_VIDEO
state_ns = EAV_VIDEO;
else
state_ns = EAV_BKANKING;
SAV_BKANKING : state_ns = INVAILD_BLANKING;
EAV_BKANKING : state_ns = INVAILD_BLANKING;
SAV_VIDEO : state_ns = VAILD_VIDEO;
EAV_VIDEO : state_ns = INVAILD_BLANKING;
VAILD_VIDEO :
if(hs_cnt == hs_rising_to_de_g + width_g - 1'b1 - 1'b1)
state_ns = SYNC1_EAV;//去EAV部分
else
state_ns = VAILD_VIDEO;
default :
state_ns = INVAILD_BLANKING;
endcase
end
always @(posedge yc422_pclk_i)
begin
if(rst)
embed_hs_vs_yc422_o <= STUFF;
else begin
if(state_cs == INVAILD_BLANKING)
embed_hs_vs_yc422_o <= STUFF;
else if(state_cs == VAILD_VIDEO)
embed_hs_vs_yc422_o <= yc422_data_i; //yc422_data_d1
else if((state_cs == SYNC1_SAV) || (state_cs == SYNC1_EAV))
embed_hs_vs_yc422_o <= 16'hffff;
else if((state_cs == SYNC2_SAV) || (state_cs == SYNC2_EAV))
embed_hs_vs_yc422_o <= 16'h0000;
else if((state_cs == SYNC3_SAV) || (state_cs == SYNC3_EAV))
embed_hs_vs_yc422_o <= 16'h0000;
else if(state_cs == SAV_BKANKING)
embed_hs_vs_yc422_o <= 16'habab;
else if(state_cs == EAV_BKANKING)
embed_hs_vs_yc422_o <= 16'hb6b6;
else if(state_cs == SAV_VIDEO)
embed_hs_vs_yc422_o <= 16'h8080;
else if(state_cs == EAV_VIDEO)
embed_hs_vs_yc422_o <= 16'h9d9d;
else
embed_hs_vs_yc422_o <= STUFF;
end
end
endmodule
embed_hs_vs_enc U_embed_hs_vs_enc_0(
. rst(rst),
. yc422_pclk_i(video_clk_148m5),
. yc422_data_i({yc_c,yc_y}),
. yc422_de_i(yc_de),
. yc422_vs_i(yc_vs),
. yc422_hs_i(yc_hs),
//--------------------------------------------------------
//视频时序参数,由CPU 通过i2c配置得到
. width_i(12'd1920), // l
. height_i(12'd1080), //
. hs_rising_to_de_i(12'd192),
. hor_total_g_i(12'd2200),
. vs_rising_to_de_i(12'd41), //L2
. ver_total_g_i(12'd1125), //L6
//----------------------------------------------------------
. video_pararm_enable_i(video_pararm_enable),
//----------------------------------------------------------
//bt.1120接口
. embed_hs_vs_pclk_o(bt1120_clk),
. embed_hs_vs_yc422_o(bt1120_yc)
);
FPGA实现BT.1120编码相关推荐
- (65)FPGA面试题-状态机编码选择原则?
1.1 FPGA面试题-状态机编码选择原则? 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-状态机编码选择原则: 5)结束语. 1.1.2 本节引言 & ...
- 用FPGA实现光端机HDB3编码设计
摘要 介绍了光端机的E1信道HDB3编码的原理和方法,给出了用FPGA实现E1信号HDB3编码的方法.得到了用Xilinx公司的集成软件ISE6.2进行HDB3编码的原理图及仿真结果.结果表明用XC2 ...
- 【FPGA】8B/10B编码--转自wiki百科
8B/10B,也叫做8字节/10字节或8B10B.8B/10B方式最初由IBM公司于1983年发明并应用于ESCON(200M互连系统),由Al Widmer和Peter Franaszek在IBM的 ...
- 视频时序与BT1120的关系
CEA-861-D视频时序: 水平方向对比: 垂直方向对比: BT.1120整体数据格式: 具体实现可参考我另外一篇文章<FPGA实现BT.1120编码>.
- Aupera:FPGA让视频编码与AI结合水到渠成
Aupera是一家专注于视频数据应用的新一代系统解决方案的创业公司,Aupera资深AI工程师Narges Afsham博士接受LiveVideoStack采访时表示,在FPGA中集成视频编码与AI是 ...
- 卷积码编码及维特比译码(Viterbi)算法的原理及其FPGA实现
引言 卷积码是一种信道纠错编码,在通信中具有广泛的应用.在发送端根据生成多项式进行卷积码编码,在接收端根据维特比(Viterbi)译码算法进行译码,能够有效抵抗信道噪声的影响,在误码率门限 ...
- 全志V5智能编码处理器详细参数介绍
全志V5智能编码处理器,支持双目摄像,并加入最新一代HawkView 5.0图像处理器与4K Smart H.265 视频编码器,进一步提高运动相机.安防监控应用场景的画质水平,帮助客户打造更具市场竞 ...
- 基于FPGA的SDI发送接口调试,FPGA+GV7700实现1080p和720p的显示
#基于FPGA的SDI发送接口调试,FPGA+GV7700实现1080p和720p的显示 上一篇文章已经调试了bt11200接口,本章将基于bt1120接口完善代码,实现1080p60Hz和720p6 ...
- 基于QoE的实时视频编码优化:低功耗,低延时,高质量
在实时通信领域,只有当Codec的优化适应了当前的网络状况,设备平台及应用场景,用户才能得到最佳的体验.在LiveVideoStackCon2018大会中声网Agora视频工程师吴晓然详细介绍了如何设 ...
- java上传图片特征码到服务器,记一个Base64编码后经网络传输产生的问题
问题:机器特征码经过网络传输之后,'+'都变成了' ' 详情:机器特征码提取了机器cpuId和mac地址信息,最后经过Base64编码后生成的字符串,一开始我使用的是 String strs = ne ...
最新文章
- android litehttp jar,灵活而智能的HTTP框架 LiteHttp
- matlab绘图z=sin(x_「matlab画三维图」Matlab 应用之绘制三维图形(基础篇) - seo实验室...
- boost::polygon模块实现多边形段相关的测试程序
- py文件转exe时包含paramiko模块出错解决方法
- HTML的SEO(搜索引擎优化)标准
- SSH框架整合截图总结(三)
- 使用Nlog记录日志到数据库
- oracle bfile备份,整理的一些oracle备份笔记 (zt)
- nginx编译包含perl模块
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined)
- 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第1节 基本概念_01maven概述
- 如何写好一份 30 K offer 的简历(建议收藏)
- 【Java进阶】Java内存模型中的happen-before是什么?
- Java 阿里云图片添加水印
- 小米手机产品全球不再使用“MI”品牌,改用“xiaomi”全称品牌
- 山东大学计算机学院李庆忠,研究生导师李庆忠:山东大学
- Lawliet|Python学习笔记3——函数
- ceonts6.8 nginx做前端代理apache做后端服务架构配置
- leaflet geojson行政区域展示
- NodeJS环境搭建以及运行Node.js项目、饿了么ui(elementui)开发模式简单介绍