github上hamsternz/FPGA_DisplayPort 的VHDL源码分析(一)

源码来源于https://github.com/hamsternz/FPGA_DisplayPort。由于我也是第一次接触这个接口,所以文中肯定有我理解错误的地方,恳请指正。要看懂代码首先还是要对协议有一定了解。所以我做的源码分析中会和协议结合起来。

激励文件test_source_800_600_RGB_444_colourbars_ch1.vhd

首先看接口信号,信号的定义在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就是块内数据按字的组合。之所以两个符号拼接起来是因为后级的GTP模块入口位宽是20位。

data的高位没有赋值是因为预留了位宽资源给2通道或4通道的情况。该源是ch1的。

初始时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

你可能感兴趣的:(video)