1. 程式人生 > >github上hamsternz/FPGA_DisplayPort 的VHDL原始碼分析(一)

github上hamsternz/FPGA_DisplayPort 的VHDL原始碼分析(一)

原始碼來源於https://github.com/hamsternz/FPGA_DisplayPort。由於我也是第一次接觸這個介面,所以文中肯定有我理解錯誤的地方,懇請指正。要看懂程式碼首先還是要對協議有一定了解。所以我做的原始碼分析中會和協議結合起來。

激勵檔案test_source_800_600_RGB_444_colourbars_ch1.v

首先看介面訊號,訊號的定義在DP協議Main Stream Attribute Data Transport章節

        M_value              : out std_logic_vector(23 downto 0);
        N_value              : out std_logic_vector(23 downto 0);

M和N用於從接收的LS_CLK(link symbol clock)中恢復Stream_CLK。協議Stream Clock Regeneration章節有詳細介紹。公式為

f_Strm_Clk = Mvid / Nvid * f_LS_Clk。

        H_visible            : out std_logic_vector(11 downto 0); --水平掃描有效畫素個數
        V_visible            : out std_logic_vector(11 downto 0); --垂直掃描有效畫素個數
        H_total              : out std_logic_vector(11 downto 0);  --水平掃描個數
        V_total              : out std_logic_vector(11 downto 0);  --垂直掃描個數
        H_sync_width         : out std_logic_vector(11 downto 0); --水平同步脈衝寬度
        V_sync_width         : out std_logic_vector(11 downto 0); --垂直同步脈衝寬度
        H_start              : out std_logic_vector(11 downto 0);     --水平脈衝起始位置
        V_start              : out std_logic_vector(11 downto 0);     --垂直脈衝起始位置
        H_vsync_active_high  : out std_logic;   --脈衝有效電平極性
        V_vsync_active_high  : out std_logic;   --脈衝有效電平極性

定義要傳送的影象:

    type a_test_data_blocks is array (0 to 64*17-1) of std_logic_vector(8 downto 0);

每個畫素位寬為9位,最高位為1時表示傳遞的是special characters。也就是8b/10b編碼時的K字

符,如下

    constant SS     : std_logic_vector(8 downto 0) := "101011100";   -- K28.2
    constant SE     : std_logic_vector(8 downto 0) := "111111101";   -- K29.7
    constant BE     : std_logic_vector(8 downto 0) := "111111011";   -- K27.7
    constant BS     : std_logic_vector(8 downto 0) := "110111100";   -- K28.5
    constant SR     : std_logic_vector(8 downto 0) := "100011100";   -- K28.0
    constant FS     : std_logic_vector(8 downto 0) := "111111110";   -- K30.7
    constant FE     : std_logic_vector(8 downto 0) := "111110111";   -- K23.7

一共有17個塊,每個塊有64個數據,協議要求每個包長為32到64.

第0個塊

    --- Block 0 - Junk
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, 
    SPARE, SPARE, SPARE, SPARE, SPARE, SPARE, SPARE, SPARE, SPARE, SPARE, 

dummy是無效的資料,spare完全是充數的,為了湊夠64個數據而存在。每個塊最後10個數據均如此

第1~12個塊

前24個是有效畫素,後面30個FS和FE包含的是鏈路層要求的填充資料。因為DP鏈路速率是固定的幾種,而視訊流的速率有很多種,所以需要在視訊流中填充使得速率達到鏈路速率。

第13個塊

    --- Block 13 - 8 x Blue, Blank Start, VB-ID (no vsync), Mvid, MAud and junk

    PIX_0,  PIX_0,  PIX_80, PIX_0,  PIX_0,  PIX_80, 
    PIX_0,  PIX_0,  PIX_80, PIX_0,  PIX_0,  PIX_80, 
    PIX_0,  PIX_0,  PIX_80, PIX_0,  PIX_0,  PIX_80, 
    PIX_0,  PIX_0,  PIX_80, PIX_0,  PIX_0,  PIX_80, 
    BS,     VB_NVS, MVID,   MAUD,   VB_NVS, MVID,  
    MAUD,   VB_NVS, MVID,   MAUD,   VB_NVS, MVID,      
    MAUD,   DUMMY,  DUMMY,  DUMMY,  DUMMY,  DUMMY, 
    DUMMY,  DUMMY,  DUMMY,  DUMMY,  DUMMY,  DUMMY, 
    DUMMY,  DUMMY,  DUMMY,  DUMMY,  DUMMY,  DUMMY, 
    SPARE,  SPARE,  SPARE,  SPARE,  SPARE,  SPARE, SPARE, SPARE, SPARE, SPARE, 

傳遞完一行資料後,BS消隱開始(Blanking Start),VB-ID的bit0為1表示傳遞完成最後一行。用於幀定位。此處為0

塊14,傳遞完一行資料後,BS消隱開始(Blanking Start),VB-ID的bit0為1表示傳遞完成最後一行。用於幀定位。此處為1

塊15,填充完一行資料後,BS消隱開始(Blanking Start),VB-ID的bit0為1表示傳遞完成最後一行。用於幀定位。此處為1

塊16 ,第54個數據為BE

 

影象傳送靠計數器控制取block中的資料完成,index是索引計數器,高5位取值0~16,對應塊編號。低6位對應塊內資料,index每個時鐘+2,取值為0到52迴圈計數,

            d0   <= test_data_blocks(to_integer(index+0));
            d1   <= test_data_blocks(to_integer(index+1));

    data(17 downto 0)  <= d1 & d0; 

所以d1 & d0就是塊內資料按字的組合

初始時index row_count line_count三個計數器都為0,此時nidex塊選擇為16,資料以BE結束,也表示接下來要傳遞有效資料

每次行掃描,row_count從0計數到131.為0時上面說了傳送的是BE,1到100時傳送畫素資料,每次24個位元組,共8個畫素,剩餘30個位元組為填充,所以100次共傳送800個畫素資料,第100次傳送塊13,在一行有效資料傳送完成後進入BS。最後31次row_count計數傳送31X8=248個無效資料,連同0時傳送的8個無效資料,一行共8+800+248=1056個數據

line_count從0到627計數,對應列掃描由0到627.每行都由BE開頭,BS結束

第600列的最後一個塊編號為塊14,BS後VB-ID的bit0為1表示傳遞完成最後一行。

之後的列為填充,但是每到一行無效畫素完成時,選擇塊15最為最後無效畫素插入BS(這麼做可能是為了插入K碼)

一幀資料傳送完成後的頭800個畫素switch_point為1,其他時刻為0