日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于FPGA的1080P 60Hz BT1120接口调试过程记录

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于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接口调试过程记录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。