#基于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. 阿里云短信发送接口调试

    1.注册阿里云账号,并开通云短信服务 开通短信服务时免费的,但是发短信需要从点钱,短信收费可以按发送条数收费 2.充值 3.申请短信签名 4.申请短信模板 5.创建AccessKey,这是很重要,是程 ...

  2. python fpga chips_基于FPGA实现JESD204B高速接口设计

    曹鹏飞 摘 要:JESD204B接口是高速ADC和DAC芯片采用的数据通信接口之一,具有传输速率高,抗干扰能力强,芯片间同步方便等优点.目前国内JESD204B 接口应用多由国外集成芯片提供,缺乏自主 ...

  3. 基于labview的温湿度数据采集_【零偏原创】基于FPGA的多路SPI接口并行数据采集系统...

    摘 要:本文简述了SPI协议,建立了基于FPGA的SPI接口电路模型,并说明其输入输出端口和数据发送和接收过程,仿真验证了在主状态机控制下10个SPI接口并行采集数据,并在FPGA开发板上进行验证. ...

  4. 创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA的 电源接口和拨码开关、JTAG仿真器接口

    TL437xF-EVM是一款广州创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA设计的开发板,底板采用沉金无铅工艺的4层板设计,尺寸为240mm* ...

  5. FPGA SATA IP控制器的SATA接口调试记录

    本文档是基于FPGA K7 SATA IP控制器的SATA接口调试记录,接口遵循标准的ACHI协议. 操作系统内核版本:5.4.18 由于K7PCIE只有3个bar,AHCI协议规定SATA控制器是在 ...

  6. 十四、基于FPGA的SDI协议介绍(一)

    1 ,概念 SDI接口是一种"数字分量串行接口",而HD-SDI接口是一种广播级的高清数字输入和输出端口,其中HD表示高清信号.由于SDI接口不能直接传送压缩数字信号,数字录像机. ...

  7. FPGA与DSP之间的EMIF接口调试

    外部设备连接接口包括外部存储器连接接口(EMIF).主机接口(HPI)等.外部存储器接口主要用来同并行存储器连接,这些存储器包括SDRAM.SBSRAM.Flash.SRAM存储器等,外部存储器接口还 ...

  8. 十四、基于FPGA的SDI协议介绍(二)

    上一文主要介绍了SDI中的PAL格式,本文主要基于XilinxFPGA的sdi IP使用展开介绍 1,SDI IP 支持协议 SD-SDI :   PAL    NTSC     HD-SDI :   ...

  9. FPGA之道(20)FPGA设计的上板调试与项目总结

    文章目录 前言 FPGA设计的上板调试 "实践是检验真理的唯一标准" 如何解决问题 如何找到问题 "时间是检验真理的第二标准" 项目总结.备份与后期维护 前言 ...

最新文章

  1. 红外感应自动出水水龙头的电路原理
  2. mysql 驱动包 bin 的意思_mysql连接数据库,用下面代码,为什么找不到驱动呢?? lib下是mysql-connector-java-5.1.15-bin.jar...
  3. Spring Boot (七)MyBatis代码自动生成和辅助插件
  4. lrzsz linux 安装目录,Linux下lrzsz软件的安装与使用
  5. python视频 神经网络 Tensorflow
  6. 【OpenCV】扫描图像、查找表、计时
  7. flex连接mysql,flex对数据库(sqlite)的操作
  8. 攻防世界——MyDriver2-397
  9. 深度linux系统老版本,Deepin Linux15.7下载
  10. 【存储】超融合(HCI)和云是什么以及区别
  11. 关于解决华硕TUF B360M-PLUS GAMING在WIN10下无网卡驱动的方法
  12. 基于股票大数据分析的Python入门实战(实践记录)(持续更新)
  13. SpringBoot替换jar包中引用的jar包(Unable to open nested entry ‘BOOT-INF/lib/**.jar‘. It has been compressed)
  14. SQL调优(SQL TUNING)并行查询提示(Hints)之pq_distribute的使用
  15. 长理2019选拔赛1.0
  16. 无法访问其它家庭组计算机,Win7电脑同一个家庭组或者工作组,电脑无法相互访问...
  17. vs2010生成的exe更改icon
  18. QQ拼音Vista平台试用:行云流水 完美兼容
  19. STM32闭环步进电机驱动器方案,原理图,源码,PCB
  20. 项目进度跟踪的最佳实践:每日站立会议

热门文章

  1. 什么时候不该使用es6箭头函数 1
  2. 【java迭代器Iterator】获取单个元素,循环遍历和删除
  3. 到底什么是Upnp?[转载]
  4. 绝地求生服务器维护多久,绝地求生更新维护公告最新 5月18日维护到几点
  5. Java毕设项目校园外卖零食商城系统计算机(附源码+系统+数据库+LW)
  6. JS_map遍历数组
  7. c++析构函数、虚析构函数、纯虚析构函数详解
  8. HashMap/HashMap存储/HashMap扩容
  9. html中树状图实现方式
  10. xlsx表格怎么做汇总统计_excel表格 的自动统计数据-excel,怎么做数据自动汇总