基于FPGA的SDI发送接口调试,FPGA+GV7700实现1080p和720p的显示
#基于FPGA的SDI发送接口调试,FPGA+GV7700实现1080p和720p的显示
上一篇文章已经调试了bt11200接口,本章将基于bt1120接口完善代码,实现1080p60Hz和720p60Hz的显示兼容。
720p60Hz的数据格式
1080p60Hz的数据格式
上板测试,显示彩条
顶层文件
module rgb_to_bt1120_top (input rst_n , input pclk ,// input t_de ,
// input t_hsync,
// input t_vsync,
// input [23:0] t_rgb ,// input [11:0] hactive,
// input [11:0] htotal ,
// input [11:0] vactive,
// input [11:0] vtotal ,output bt1120_pclk ,output [15:0] bt1120_ycbcr
);parameter HACTIVE = 12'd1920;
parameter HTOTAL = 12'd2200;
parameter VACTIVE = 12'd1080;
parameter VTOTAL = 12'd1125;wire hsync;
wire vsync;
wire de ;
wire[15:0] ycbcr;wire t_de ;
wire t_hsync;
wire t_vsync;
wire[23:0] t_rgb ;reg [4:0] cnt ;
reg param_en;tpg_ctr(.clk (pclk ), //input .rst_n(rst_n ), //input .de (t_de ), //output reg .hsync(t_hsync), //output reg .vsync(t_vsync), //output reg .rgb (t_rgb ) //output reg[23:0]
);rgb_to_ycbcr422_top rgb_to_ycbcr422_top(.clk (pclk ),.rst_n (rst_n ),.i_de (t_de ), .i_hsync(t_hsync), .i_vsync(t_vsync), .i_data (t_rgb ), .o_hsync (hsync ),.o_vsync (vsync ),.o_data_vld (de ),.o_ycbcr (ycbcr )
);ycbcr422_to_bt1120 ycbcr422_to_bt1120(.rst_n (rst_n ),.pclk (pclk ),.param_vld (param_en),.hactive (HACTIVE ), //参数获取 :一行有效数据个数 例1920 、1280.htotal (HTOTAL ), //参数获取 :一行数据总数 例2200 、1650.vactive (VACTIVE ), //参数获取 :一帧数据的有效行数 例1080 、720.vtotal (VTOTAL ), //参数获取 :一帧数据的行总数 例1125 、750 .data_de (de ),.hsync (hsync ),.vsync (vsync ),.ycbcr (ycbcr ), .bt1120_pclk (bt1120_pclk ),.bt1120_ycbcr (bt1120_ycbcr));always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt <= 5'b0;endelse if(cnt<5'd30)begincnt <= cnt + 1;end
endalways @(posedge clk or negedge rst_n)beginif(!rst_n)beginparam_en <= 1'b0;endelse if(cnt==5'd30)beginparam_en <= 1'b1;end
end
endmodule
GBR to YUV422顶层
module rgb_to_ycbcr422_top(input clk ,input rst_n ,input i_de ,input i_hsync,input i_vsync,input[23:0] i_data ,output o_hsync,output o_vsync,output o_data_vld,output[15:0] o_ycbcr
);wire hsync ;
wire vsync ;
wire data_vld ;
wire [7:0] lumi ;
wire [7:0] cb ;
wire [7:0] cr ; rgb_to_ycbcr444 rgb_to_ycbcr444(.clk (clk), .i_r_8b (i_data[23:16]), .i_g_8b (i_data[15:8] ), .i_b_8b (i_data[7:0] ), .i_h_sync (i_hsync ),.i_v_sync (i_vsync ),.i_data_en(i_de ),.o_y_8b (lumi ),.o_cb_8b (cb ),.o_cr_8b (cr ), .o_h_sync (hsync ),.o_v_sync (vsync ), .o_data_en(data_vld )
);ycbcr444_to_ycbcr422 ycbcr444_to_ycbcr422(.clk (clk ),.rst_n (rst_n),.i_h_sync (hsync ), .i_v_sync (vsync ), .i_data_en(data_vld ), .i_y (lumi ), .i_cb (cb ), .i_cr (cr ), .o_h_sync (o_hsync ), .o_v_sync (o_vsync ), .o_data_en(o_data_vld), .o_ycbcr (o_ycbcr )
);endmodule
RGB to YUV444
/*
RGB 转 Ycbcr 算法
计算公式:
Y = 0.183R + 0.614G + 0.062B + 16;
cb = -0.101R - 0.338G + 0.439B + 128;
cr = 0.439R - 0.399G - 0.040B + 128;其中,时序在计算过程中完全没有用到输入到输出有三个 clock 的时延。第一级流水线计算所有乘法;第二级流水线计算所有加法,把正的和负的分开进行加法;第三级流水线计算最终的和,若为负数取 0;
*/
`timescale 1ns/1ps
module rgb_to_ycbcr444(input clk,input [7 : 0] i_r_8b,input [7 : 0] i_g_8b,input [7 : 0] i_b_8b,input i_h_sync,input i_v_sync,input i_data_en,output [7 : 0] o_y_8b,output [7 : 0] o_cb_8b,output [7 : 0] o_cr_8b,output o_h_sync,output o_v_sync, output o_data_en
);//multiply 256
parameter para_0183_10b = 10'd47; //0.183 定点数
parameter para_0614_10b = 10'd157;
parameter para_0062_10b = 10'd16;
parameter para_0101_10b = 10'd26;
parameter para_0338_10b = 10'd86;
parameter para_0439_10b = 10'd112;
parameter para_0399_10b = 10'd102;
parameter para_0040_10b = 10'd10;
parameter para_16_18b = 18'd4096;
parameter para_128_18b = 18'd32768;wire sign_cb;
wire sign_cr;
reg[17: 0] mult_r_for_y_18b;
reg[17: 0] mult_r_for_cb_18b;
reg[17: 0] mult_r_for_cr_18b;reg[17: 0] mult_g_for_y_18b;
reg[17: 0] mult_g_for_cb_18b;
reg[17: 0] mult_g_for_cr_18b;reg[17: 0] mult_b_for_y_18b;
reg[17: 0] mult_b_for_cb_18b;
reg[17: 0] mult_b_for_cr_18b;reg[17: 0] add_y_0_18b;
reg[17: 0] add_cb_0_18b;
reg[17: 0] add_cr_0_18b;reg[17: 0] add_y_1_18b;
reg[17: 0] add_cb_1_18b;
reg[17: 0] add_cr_1_18b;reg[17: 0] result_y_18b;
reg[17: 0] result_cb_18b;
reg[17: 0] result_cr_18b;reg[9:0] y_tmp;
reg[9:0] cb_tmp;
reg[9:0] cr_tmp;reg i_h_sync_delay_1;
reg i_v_sync_delay_1;
reg i_data_en_delay_1;reg i_h_sync_delay_2;
reg i_v_sync_delay_2;
reg i_data_en_delay_2;reg i_h_sync_delay_3;
reg i_v_sync_delay_3;
reg i_data_en_delay_3;reg i_h_sync_delay_4 ;
reg i_v_sync_delay_4 ;
reg i_data_en_delay_4;initial beginmult_r_for_y_18b <= 18'd0;mult_r_for_cb_18b <= 18'd0;mult_r_for_cr_18b <= 18'd0;mult_g_for_y_18b <= 18'd0;mult_g_for_cb_18b <= 18'd0;mult_g_for_cr_18b <= 18'd0;mult_b_for_y_18b <= 18'd0;mult_g_for_cb_18b <= 18'd0;mult_b_for_cr_18b <= 18'd0;add_y_0_18b <= 18'd0;add_cb_0_18b <= 18'd0;add_cr_0_18b <= 18'd0;add_y_1_18b <= 18'd0;add_cb_1_18b <= 18'd0;add_cr_1_18b <= 18'd0;result_y_18b <= 18'd0;result_cb_18b <= 18'd0;result_cr_18b <= 18'd0;i_h_sync_delay_1 <= 1'd0;i_v_sync_delay_1 <= 1'd0;i_data_en_delay_1 <= 1'd0;i_h_sync_delay_2 <= 1'd0;i_v_sync_delay_2 <= 1'd0;i_data_en_delay_2 <= 1'd0;
end//LV1 pipeline : mult
always @ (posedge clk)beginmult_r_for_y_18b <= i_r_8b * para_0183_10b;mult_r_for_cb_18b <= i_r_8b * para_0101_10b;mult_r_for_cr_18b <= i_r_8b * para_0439_10b;
endalways @ (posedge clk)beginmult_g_for_y_18b <= i_g_8b * para_0614_10b;mult_g_for_cb_18b <= i_g_8b * para_0338_10b;mult_g_for_cr_18b <= i_g_8b * para_0399_10b;
endalways @ (posedge clk)beginmult_b_for_y_18b <= i_b_8b * para_0062_10b;mult_b_for_cb_18b <= i_b_8b * para_0439_10b;mult_b_for_cr_18b <= i_b_8b * para_0040_10b;
end//LV2 pipeline : add
always @ (posedge clk)beginadd_y_0_18b <= mult_r_for_y_18b + mult_g_for_y_18b;add_y_1_18b <= mult_b_for_y_18b + para_16_18b;add_cb_0_18b <= mult_b_for_cb_18b + para_128_18b;add_cb_1_18b <= mult_r_for_cb_18b + mult_g_for_cb_18b;add_cr_0_18b <= mult_r_for_cr_18b + para_128_18b;add_cr_1_18b <= mult_g_for_cr_18b + mult_b_for_cr_18b;
end
//LV3 pipeline : y + cb + cr
assign sign_cb = (add_cb_0_18b >= add_cb_1_18b);
assign sign_cr = (add_cr_0_18b >= add_cr_1_18b);always @ (posedge clk)beginresult_y_18b <= add_y_0_18b + add_y_1_18b;result_cb_18b <= sign_cb ? (add_cb_0_18b - add_cb_1_18b) : 18'd0;result_cr_18b <= sign_cr ? (add_cr_0_18b - add_cr_1_18b) : 18'd0;
endalways @ (posedge clk)beginy_tmp <= result_y_18b[17:8] + {9'd0,result_y_18b[7]};cb_tmp <= result_cb_18b[17:8] + {9'd0,result_cb_18b[7]};cr_tmp <= result_cr_18b[17:8] + {9'd0,result_cr_18b[7]};
end//output
assign o_y_8b = (y_tmp[9:8] == 2'b00) ? y_tmp[7 : 0] : 8'hFF;
assign o_cb_8b = (cb_tmp[9:8] == 2'b00) ? cb_tmp[7 : 0] : 8'hFF;
assign o_cr_8b = (cr_tmp[9:8] == 2'b00) ? cr_tmp[7 : 0] : 8'hFF;always @ (posedge clk)begini_h_sync_delay_1 <= i_h_sync;i_v_sync_delay_1 <= i_v_sync;i_data_en_delay_1 <= i_data_en;i_h_sync_delay_2 <= i_h_sync_delay_1;i_v_sync_delay_2 <= i_v_sync_delay_1;i_data_en_delay_2 <= i_data_en_delay_1;i_h_sync_delay_3 <= i_h_sync_delay_2;i_v_sync_delay_3 <= i_v_sync_delay_2;i_data_en_delay_3 <= i_data_en_delay_2;i_h_sync_delay_4 <= i_h_sync_delay_3 ;i_v_sync_delay_4 <= i_v_sync_delay_3 ;i_data_en_delay_4 <= i_data_en_delay_3;endassign o_h_sync = i_h_sync_delay_4;
assign o_v_sync = i_v_sync_delay_4;
assign o_data_en = i_data_en_delay_4;endmodule
YUV444 to YUV422
`timescale 1ns/1ps
module ycbcr444_to_ycbcr422(input clk ,input rst_n ,input i_h_sync , input i_v_sync , input i_data_en , input [7:0] i_y , input [7:0] i_cb , input [7:0] i_cr , output reg o_h_sync , output reg o_v_sync , output reg o_data_en , output [15:0] o_ycbcr
);reg flag ;
reg [7:0] o_y;
reg [7:0] o_cbcr;always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginflag <= 1'b1 ;endelse if(i_data_en)beginflag <= ~flag ;endelse beginflag <= 1'b1 ;end
endalways @(posedge clk )beginif(flag)begino_cbcr <= i_cb;endelse begino_cbcr <= i_cr;end
endalways @(posedge clk )begino_h_sync <= i_h_sync;o_v_sync <= i_v_sync;o_data_en <= i_data_en;o_y <= i_y;
endassign o_ycbcr = {o_y ,o_cbcr} ;endmodule
YUV422 to BT1120
/* 定时基准码 <0xff 0x00 0x00 xyz>* 其中xyz为如下的取值范围:* 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 ycbcr422_to_bt1120(input rst_n ,input pclk ,input param_vld , //参数有效input [11:0] para_hactive, //参数获取 :一行有效数据个数 例1920 、1280input [11:0] para_htotal , //参数获取 :一行数据总数 例2200 、1650input [11:0] para_vactive, //参数获取 :一帧数据的有效行数 例1080 、720input [11:0] para_vtotal , //参数获取 :一帧数据的行总数 例1125 、750input 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;wire full ;
reg rd_en ;
wire[15:0] rd_data /* synthesis keep */;
wire empty ;reg [3:0] state_c /* synthesis preserve */;
reg [3:0] state_n ;
wire blank2sav ;
wire video2eav ;reg data_de0 ;
reg hsync0 /* synthesis noprune*/ ;
reg vsync0 ;
reg [15:0] ycbcr0 ;
reg data_de1 ;
reg hsync1 /* synthesis noprune*/ ;
reg vsync1 ;
reg [15:0] ycbcr1 ;
wire v_pos ;reg [11:0] cnt_h ;
reg [11:0] cnt_v ; reg param_vld0;
reg param_vld1;
reg param_gain;reg [11:0] hactive;
reg [11:0] htotal ;
reg [11:0] vactive;
reg [11:0] vtotal ;reg [11:0] hactive0;
reg [11:0] htotal0 ;
reg [11:0] vactive0;
reg [11:0] vtotal0 ;reg [11:0] hactive1;
reg [11:0] htotal1 ;
reg [11:0] vactive1;
reg [11:0] vtotal1 ;reg [15:0] bt1120_ycbcr1;
reg [15:0] bt1120_ycbcr0;///下面是视频参数获取部分/////上游传过来的参数有效脉冲打拍
always @(posedge pclk)beginparam_vld0 <= param_vld ;param_vld1 <= param_vld0;
endalways @(posedge pclk)beginhactive0 <= para_hactive;htotal0 <= para_htotal ; vactive0 <= para_vactive;vtotal0 <= para_vtotal ;hactive1 <= hactive0;htotal1 <= htotal0 ; vactive1 <= vactive0;vtotal1 <= vtotal0 ;
end//assign param_gain = !param_vld1 && param_vld0 ;always @(posedge pclk or negedge rst_n)beginif(rst_n==1'b0)param_gain <= 1'b0;else if(!param_vld1 && param_vld0)param_gain <= 1'b1;else param_gain <= 1'b0;
end//获取时序参数
always @(posedge pclk or negedge rst_n)beginif(rst_n==1'b0)beginhactive <= 12'b0;htotal <= 12'b0; vactive <= 12'b0;vtotal <= 12'b0;endelse if(param_gain && htotal != htotal1)beginhactive <= hactive1;htotal <= htotal1 ; vactive <= vactive1;vtotal <= vtotal1 ;endelse beginhactive <= hactive ;htotal <= htotal ; vactive <= vactive ;vtotal <= vtotal ;end
end///下面是视频输入输出部分///assign bt1120_pclk = pclk ;yc2bt_fifo yc2bt_fifo_inst0
(.clock (pclk ),.data (ycbcr1 ),.wrreq (data_de1),.full (full ),.rdreq (rd_en ),.q (rd_data ),.empty (empty )
);//read en
always @(posedge pclk or negedge rst_n)beginif(rst_n==1'b0)beginrd_en <= 1'b0 ;endelse if(cnt_v >= vstart && cnt_v < (vactive + vstart))beginif(cnt_h >= (htotal-hactive - 1) && cnt_h < htotal-1)rd_en <= 1'b1 ;elserd_en <= 1'b0 ;endelse beginrd_en <= 1'b0 ;end
endalways@(posedge pclk 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 == htotal-hactive-5; //提前5个时钟进入start active ,因为要发送ff 00 00 xyz
assign video2eav = state_c==VAILD_VIDEO && cnt_h == htotal-1; //发送一行数据结束//视频输入打拍
always @(posedge pclk 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 pclk )beginif(v_pos || cnt_h == htotal)cnt_h <= 12'b1;else cnt_h <= cnt_h + 1;
end//一帧计数器
always @(posedge pclk )beginif(v_pos)cnt_v <= 12'b1;else if(cnt_h == htotal)beginif(cnt_v == vtotal)cnt_v <= 12'b0;elsecnt_v <= cnt_v + 1;end
end //出数据
always @(posedge pclk or negedge rst_n)beginif(rst_n==1'b0)beginbt1120_ycbcr1 <= STUFF ;endelse begin case(state_c)BLANKING:begin bt1120_ycbcr1<= STUFF ; endCODE_SAV1:begin bt1120_ycbcr1<= 16'hffff ; endCODE_SAV2:begin bt1120_ycbcr1<= 16'h0 ; end CODE_SAV3:begin bt1120_ycbcr1<= 16'h0 ; end CODE_SAV4:beginif(cnt_v < vstart ||(cnt_v >= (vactive + vstart) && cnt_v <= vtotal)) //消隐阶段要发送的start activebt1120_ycbcr1<= 16'habab ; else if(cnt_v >= vstart && cnt_v <(vactive + vstart)) //非消隐阶段要发送的start activebt1120_ycbcr1<= 16'h8080 ; endVAILD_VIDEO:begin bt1120_ycbcr1<= rd_data ; endCODE_EAV1:beginbt1120_ycbcr1 <= 16'hffff;endCODE_EAV2:beginbt1120_ycbcr1 <= 16'h0;endCODE_EAV3:beginbt1120_ycbcr1 <= 16'h0;endCODE_EAV4:beginif(cnt_v < vstart ||(cnt_v >= (vactive + vstart) && cnt_v <= vtotal)) //消隐阶段要发送的end activebt1120_ycbcr1<= 16'hb6b6 ;else if(cnt_v >= vstart && cnt_v < (vactive + vstart) ) //非消隐阶段要发送的end activebt1120_ycbcr1<= 16'h9d9d ;end endcase end
end//output data
always @(posedge pclk )beginbt1120_ycbcr0 <= bt1120_ycbcr1;bt1120_ycbcr <= bt1120_ycbcr0;
endendmodule
彩条数据文件
module tpg_ctr(input clk , input rst_n,output reg de ,output reg hsync,output reg vsync,output reg[23:0] rgb
);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; //数据有效结束,以时钟为单位reg [11:0] cnt_h;
reg [11:0] cnt_v;
reg [11:0] cnt_de;//一行数据的计数器
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//对DE信号进行计数
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_de <= 12'b0;endelse if(de)begincnt_de <= cnt_de + 1;endelse begincnt_de <= 12'b0;end
end//产生数据有效信号
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginde <= 1'b0 ;rgb <= 24'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 ;if(cnt_de<12'd383) rgb <= 24'hffffff; //白else if(cnt_de>=12'd383 && cnt_de<12'd767) rgb <= 24'h000000; //黑else if(cnt_de>=12'd767 && cnt_de<12'd1152)rgb <= 24'hff0000; //红else if(cnt_de>=12'd1152 && cnt_de<12'd1536)rgb <= 24'h00ff00; //绿else if(cnt_de>=12'd1536)rgb <= 24'h0000ff; //蓝endelse beginde <= 1'b0 ;rgb <= 24'b0;endend
endendmodule
modelsim仿真文件
`timescale 1 ns/1psmodule tb_bt1120();reg clk ;
reg rst_n;reg[11:0] hactive;
reg[11:0] hsyncw ;
reg[11:0] hstart ;
reg[11:0] htotal ;reg[11:0] vactive;
reg[11:0] vsyncw ;
reg[11:0] vstart ;
reg[11:0] vtotal ;reg t_de ;
reg t_vsync ;
reg t_hsync ;
reg[23:0] t_rgb ;reg[11:0] cnt_h ;
reg[11:0] cnt_v ;
reg[11:0] tcnt_h;
reg[11:0] tcnt_v;//uut的输出信号
wire bt1120_clk;
wire[15:0] bt1120_data;//时钟周期,单位为ns,可在此修改时钟周期。
parameter CYCLE = 7;//复位时间,此时表示复位3个时钟周期的时间。
parameter RST_TIME = 20 ;rgb_to_bt1120 u_rgb_to_bt1120(.rst_n (rst_n ), //input .pclk (clk ), //input .t_de (t_de ), //input [15:0] .t_hsync (t_hsync), //input .t_vsync (t_vsync), //input .t_rgb (t_rgb ), //input .param_vld(param_en),.hactive (hactive ), .htotal (htotal ), .vactive (vactive ), .vtotal (vtotal ), //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'd1121; //有效数据的最后一行,以行为单位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;param_en= 1'b0 ;hactive = 12'd0 ;htotal = 12'd0 ; vactive = 12'd0 ;vtotal = 12'd0 ;#2;rst_n = 0;#(CYCLE*RST_TIME);rst_n = 1;param_en= 1'b0 ;hactive = 12'd1920 ;htotal = 12'd2200 ; vactive = 12'd1080 ;vtotal = 12'd1125 ;
end//一行数据的计数器
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begincnt_h <= 12'b1 ;endelse beginif(cnt_h == h_total)cnt_h <= 12'b1 ;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'b1 ;endelse if(cnt_h == h_total)beginif(cnt_v == v_total)cnt_v <= 12'b1 ;elsecnt_v <= cnt_v + 1 ;end
end//产生行信号
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begint_hsync <= 1'b0 ;endelse if(cnt_h <= hsync_pw )begint_hsync <= 1'b1 ;endelse begint_hsync <= 1'b0 ;end
end//产生场信号
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begint_vsync <= 1'b0 ;endelse if(cnt_v <= vsync_pw )begint_vsync <= 1'b1 ;endelse begint_vsync <= 1'b0 ;end
end//产生rgb数据和de有效信号
always @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begint_de <= 1'b0 ;t_rgb <= 24'b0;endelse if(cnt_v >= data_f_enabel && cnt_v <= data_e_enabel)beginif(cnt_h > data_de_start && cnt_h <= 12'd576 )begint_de <= 1'b1 ;t_rgb <= 24'hffffff;endelse if(cnt_h > 12'd576 && cnt_h <= 12'd960)begin t_de <= 1'b1 ;t_rgb <= 24'h000000; //黑endelse if(cnt_h > 12'd960 && cnt_h <= 12'd1344)begint_de <= 1'b1 ;t_rgb <= 24'hff0000; //红endelse if(cnt_h > 12'd1344 && cnt_h <= 12'd1728)begint_de <= 1'b1 ;t_rgb <= 24'h00ff00; //绿endelse if(cnt_h > 12'd1728 && cnt_h <= 12'd2112)begint_de <= 1'b1 ;t_rgb <= 24'hff; //蓝endelse begint_de <= 1'b0 ;t_rgb <= 24'h0;endendelse begint_de <= 1'b0 ;t_rgb <= 24'h0;end
endalways @(posedge clk)begintcnt_h <= cnt_h ;tcnt_v <= cnt_v ;
endendmodule
对顶层文件做一些修改,用于modelsim测试
module rgb_to_bt1120 (input rst_n , input pclk ,input t_de ,input t_hsync,input t_vsync,input [23:0] t_rgb ,input param_vld,input [11:0] hactive,input [11:0] htotal , input [11:0] vactive,input [11:0] vtotal ,output bt1120_pclk ,output [15:0] bt1120_ycbcr
);wire hsync;
wire vsync;
wire de ;
wire[15:0] ycbcr;
wire param_vld;rgb_to_ycbcr422_top rgb_to_ycbcr422_top(.clk (pclk ),.rst_n (rst_n ),.i_de (t_de ), .i_hsync(t_hsync), .i_vsync(t_vsync), .i_data (t_rgb ), .o_hsync (hsync ),.o_vsync (vsync ),.o_data_vld (de ),.o_ycbcr (ycbcr )
);ycbcr422_to_bt1120 ycbcr422_to_bt1120(.rst_n (rst_n ),.pclk (pclk ),.param_vld (param_vld),.hactive (hactive), //参数获取 :一行有效数据个数 例1920 、1280.htotal (htotal ), //参数获取 :一行数据总数 例2200 、1650.vactive (vactive), //参数获取 :一帧数据的有效行数 例1080 、720.vtotal (vtotal ), //参数获取 :一帧数据的行总数 例1125 、750 .data_de (de ),.hsync (hsync ),.vsync (vsync ),.ycbcr (ycbcr ), .bt1120_pclk (bt1120_pclk ),.bt1120_ycbcr (bt1120_ycbcr));endmodule
测试结果
基于FPGA的SDI发送接口调试,FPGA+GV7700实现1080p和720p的显示相关推荐
- 阿里云短信发送接口调试
1.注册阿里云账号,并开通云短信服务 开通短信服务时免费的,但是发短信需要从点钱,短信收费可以按发送条数收费 2.充值 3.申请短信签名 4.申请短信模板 5.创建AccessKey,这是很重要,是程 ...
- python fpga chips_基于FPGA实现JESD204B高速接口设计
曹鹏飞 摘 要:JESD204B接口是高速ADC和DAC芯片采用的数据通信接口之一,具有传输速率高,抗干扰能力强,芯片间同步方便等优点.目前国内JESD204B 接口应用多由国外集成芯片提供,缺乏自主 ...
- 基于labview的温湿度数据采集_【零偏原创】基于FPGA的多路SPI接口并行数据采集系统...
摘 要:本文简述了SPI协议,建立了基于FPGA的SPI接口电路模型,并说明其输入输出端口和数据发送和接收过程,仿真验证了在主状态机控制下10个SPI接口并行采集数据,并在FPGA开发板上进行验证. ...
- 创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA的 电源接口和拨码开关、JTAG仿真器接口
TL437xF-EVM是一款广州创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA设计的开发板,底板采用沉金无铅工艺的4层板设计,尺寸为240mm* ...
- FPGA SATA IP控制器的SATA接口调试记录
本文档是基于FPGA K7 SATA IP控制器的SATA接口调试记录,接口遵循标准的ACHI协议. 操作系统内核版本:5.4.18 由于K7PCIE只有3个bar,AHCI协议规定SATA控制器是在 ...
- 十四、基于FPGA的SDI协议介绍(一)
1 ,概念 SDI接口是一种"数字分量串行接口",而HD-SDI接口是一种广播级的高清数字输入和输出端口,其中HD表示高清信号.由于SDI接口不能直接传送压缩数字信号,数字录像机. ...
- FPGA与DSP之间的EMIF接口调试
外部设备连接接口包括外部存储器连接接口(EMIF).主机接口(HPI)等.外部存储器接口主要用来同并行存储器连接,这些存储器包括SDRAM.SBSRAM.Flash.SRAM存储器等,外部存储器接口还 ...
- 十四、基于FPGA的SDI协议介绍(二)
上一文主要介绍了SDI中的PAL格式,本文主要基于XilinxFPGA的sdi IP使用展开介绍 1,SDI IP 支持协议 SD-SDI : PAL NTSC HD-SDI : ...
- FPGA之道(20)FPGA设计的上板调试与项目总结
文章目录 前言 FPGA设计的上板调试 "实践是检验真理的唯一标准" 如何解决问题 如何找到问题 "时间是检验真理的第二标准" 项目总结.备份与后期维护 前言 ...
最新文章
- 红外感应自动出水水龙头的电路原理
- mysql 驱动包 bin 的意思_mysql连接数据库,用下面代码,为什么找不到驱动呢?? lib下是mysql-connector-java-5.1.15-bin.jar...
- Spring Boot (七)MyBatis代码自动生成和辅助插件
- lrzsz linux 安装目录,Linux下lrzsz软件的安装与使用
- python视频 神经网络 Tensorflow
- 【OpenCV】扫描图像、查找表、计时
- flex连接mysql,flex对数据库(sqlite)的操作
- 攻防世界——MyDriver2-397
- 深度linux系统老版本,Deepin Linux15.7下载
- 【存储】超融合(HCI)和云是什么以及区别
- 关于解决华硕TUF B360M-PLUS GAMING在WIN10下无网卡驱动的方法
- 基于股票大数据分析的Python入门实战(实践记录)(持续更新)
- SpringBoot替换jar包中引用的jar包(Unable to open nested entry ‘BOOT-INF/lib/**.jar‘. It has been compressed)
- SQL调优(SQL TUNING)并行查询提示(Hints)之pq_distribute的使用
- 长理2019选拔赛1.0
- 无法访问其它家庭组计算机,Win7电脑同一个家庭组或者工作组,电脑无法相互访问...
- vs2010生成的exe更改icon
- QQ拼音Vista平台试用:行云流水 完美兼容
- STM32闭环步进电机驱动器方案,原理图,源码,PCB
- 项目进度跟踪的最佳实践:每日站立会议
热门文章
- 什么时候不该使用es6箭头函数 1
- 【java迭代器Iterator】获取单个元素,循环遍历和删除
- 到底什么是Upnp?[转载]
- 绝地求生服务器维护多久,绝地求生更新维护公告最新 5月18日维护到几点
- Java毕设项目校园外卖零食商城系统计算机(附源码+系统+数据库+LW)
- JS_map遍历数组
- c++析构函数、虚析构函数、纯虚析构函数详解
- HashMap/HashMap存储/HashMap扩容
- html中树状图实现方式
- xlsx表格怎么做汇总统计_excel表格 的自动统计数据-excel,怎么做数据自动汇总