在我們之前的學習中,了解到HDMI是一種全數字化視頻和聲音發送接口,可以發送音頻以及視頻信號。HDMI向下兼容DVI,DVI只能傳輸視頻信號。HDMI和DVI接口協議在物理層均使用TMDS標準來傳輸音頻或視頻信號,接下來就著重了解一下TMDS編碼。
TMDS(最小化傳輸差分信號)中,有四個通道,其中包含了三個數據通道和一個時鐘通道。其中數據通道用來傳輸顏色、音頻、控制等信號。HDMI默認使用RGB(RGB888)三個數據通道,當然也可以是亮度和色度信息(YCrCb,44或者42)。
上圖為HDMI的鏈接框架;
通道0傳輸的數據為:B分量的視頻數據、行場同步信號、音頻信號。
通道0傳輸的數據為:G分量的視頻數據、控制信號、音頻信號。
通道0傳輸的數據為:R分量的視頻數據、控制信號、音頻信號。
不同的數據在TMDS數據通道中在三種不同的周期中發送。
在TMDS傳輸標準中,不論是視頻信號、控制信號還是輔助信號,都是以10bit的數據傳輸,所以需要對這三個信號進行編碼,分別采用不同的編碼方式。
在此,我們著重說一下視頻編碼,在Xilinx官方給出的一個編碼示意圖中,我們可以清楚整個的編碼流程:
圖中也體現出了控制信號的編碼方式:
會對應特定的四個值中的一個。
編碼如下:
1 `timescale 1 ps / 1ps 2 3 module dvi_encoder ( 4 input clkin, // pixel clock input 5 input rstin, // async. reset input (active high) 6 input [7:0] din, // data inputs: expect registered 7 input c0, // c0 input 8 input c1, // c1 input 9 input de, // de input 10 output reg [9:0] dout // data outputs 11 ); 12 13 //////////////////////////////////////////////////////////// 14 // Counting number of 1s and 0s for each incoming pixel 15 // component. Pipe line the result. 16 // Register Data Input so it matches the pipe lined adder 17 // output 18 //////////////////////////////////////////////////////////// 19 reg [3:0] n1d; //number of 1s in din 20 reg [7:0] din_q; 21 22 //計算像素數據中“1”的個數 23 always @ (posedge clkin) begin 24 n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7]; 25 26 din_q <=#1 din; 27 end 28 29 /////////////////////////////////////////////////////// 30 // Stage 1: 8 bit -> 9 bit 31 // Refer to DVI 1.0 Specification, page 29, Figure 3-5 32 /////////////////////////////////////////////////////// 33 wire decision1; 34 35 assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0)); 36 37 wire [8:0] q_m; 38 assign q_m[0] = din_q[0]; 39 assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]); 40 assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]); 41 assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]); 42 assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]); 43 assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]); 44 assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]); 45 assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]); 46 assign q_m[8] = (decision1) ? 1'b0 : 1'b1; 47 48 ///////////////////////////////////////////////////////// 49 // Stage 2: 9 bit -> 10 bit 50 // Refer to DVI 1.0 Specification, page 29, Figure 3-5 51 ///////////////////////////////////////////////////////// 52 reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m 53 always @ (posedge clkin) begin 54 n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]; 55 n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]); 56 end 57 58 parameter CTRLTOKEN0 = 10'b1101010100; 59 parameter CTRLTOKEN1 = 10'b0010101011; 60 parameter CTRLTOKEN2 = 10'b0101010100; 61 parameter CTRLTOKEN3 = 10'b1010101011; 62 63 reg [4:0] cnt; //disparity counter, MSB is the sign bit 64 wire decision2, decision3; 65 66 assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m); 67 ///////////////////////////////////////////////////////////////////////// 68 // [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)] 69 ///////////////////////////////////////////////////////////////////////// 70 assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m)); 71 72 //////////////////////////////////// 73 // pipe line alignment 74 //////////////////////////////////// 75 reg de_q, de_reg; 76 reg c0_q, c1_q; 77 reg c0_reg, c1_reg; 78 reg [8:0] q_m_reg; 79 80 always @ (posedge clkin) begin 81 de_q <=#1 de; 82 de_reg <=#1 de_q; 83 84 c0_q <=#1 c0; 85 c0_reg <=#1 c0_q; 86 c1_q <=#1 c1; 87 c1_reg <=#1 c1_q; 88 89 q_m_reg <=#1 q_m; 90 end 91 92 /////////////////////////////// 93 // 10-bit out 94 // disparity counter 95 /////////////////////////////// 96 always @ (posedge clkin or posedge rstin) begin 97 if(rstin) begin 98 dout <= 10'h0; 99 cnt <= 5'h0; 100 end else begin 101 if (de_reg) begin 102 if(decision2) begin 103 dout[9] <=#1 ~q_m_reg[8]; 104 dout[8] <=#1 q_m_reg[8]; 105 dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0]; 106 107 cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m); 108 end else begin 109 if(decision3) begin 110 dout[9] <=#1 1'b1; 111 dout[8] <=#1 q_m_reg[8]; 112 dout[7:0] <=#1 ~q_m_reg[7:0]; 113 114 cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m); 115 end else begin 116 dout[9] <=#1 1'b0; 117 dout[8] <=#1 q_m_reg[8]; 118 dout[7:0] <=#1 q_m_reg[7:0]; 119 120 cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m); 121 end 122 end 123 end else begin 124 case ({c1_reg, c0_reg}) 125 2'b00: dout <=#1 CTRLTOKEN0; 126 2'b01: dout <=#1 CTRLTOKEN1; 127 2'b10: dout <=#1 CTRLTOKEN2; 128 default: dout <=#1 CTRLTOKEN3; 129 endcase 130 131 cnt <=#1 5'h0; 132 end 133 end 134 end 135 136 endmodule
編碼完成后,對數據我們需要進行并串轉換,此操作我們可以使用原語OSERDES2實現10-to-1的過程。最后用OBUFDS將串行數據轉換為差分信號輸出即可。
審核編輯:劉清
-
FPGA
+關注
關注
1629文章
21750瀏覽量
604108 -
RGB
+關注
關注
4文章
799瀏覽量
58563 -
HDMI接口
+關注
關注
1文章
134瀏覽量
34087 -
TMDS
+關注
關注
1文章
22瀏覽量
15517 -
信號編碼
+關注
關注
0文章
3瀏覽量
6270
原文標題:基于FPGA的TMDS編碼
文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術江湖】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論