原创 又进一步

2010-4-17 23:19 2582 3 3 分类: FPGA/CPLD

        终于有时间写日志了,这几周还真是忙啊,呵呵!


        高速数据传输方面有了新的进展。我将向导生成的例子从头到尾研究了几遍,发现它包含以下几个模块:ROCKETIO模块,发送数据模块、接收检测模块、时钟管理模块。由于整个模块比较庞大,为了方便研究,我将检测模块去掉,因为检测模块属于附属模块,不会影响整个系统的工作。但是,问题出现了,去掉上述模块后,观测发送接收数据,发现接收数据和发送数据不符,不过倒是周期出现的。这个问题困扰了我很久,仔细观察检测模块后,发现其有如下端口:


    -- User Interface
    RX_DATA                  : in  std_logic_vector((RX_DATA_WIDTH-1) downto 0);
    RX_ENMCOMMA_ALIGN        : out std_logic;
    RX_ENPCOMMA_ALIGN        : out std_logic;
    RX_ENCHAN_SYNC           : out std_logic;
    RX_CHANBOND_SEQ          : in  std_logic;


    -- Control Interface
    INC_IN                   : in std_logic;
    INC_OUT                  : out std_logic;
    PATTERN_MATCH_N          : out std_logic;
    RESET_ON_ERROR           : in std_logic;
   
    -- Error Monitoring
    ERROR_COUNT              : out std_logic_vector(7 downto 0);


    -- System Interface
    USER_CLK                 : in std_logic;      
    SYSTEM_RESET             : in std_logic


经过分析后,问题只能是由User Interface中的RX_ENMCOMMA_ALIGN,RX_ENPCOMMA_ALIGN两个端口引起的,因为只有这两个端口与ROCKETIO模块相连接,GTX手册是这样解释的:


Aligns the byte boundary when comma minus is detected


Aligns the byte boundary when comma plus is detected.



意思就是这两个端口是用来使能边界检测的,难怪接收数据不对,而且是周期的,我将这两个端口直接置1,就是一直使能边界检测,再次测试时,完全OK了,问题解决!


第二步,我将发送数据模块替换掉,发送自己产生的数据,代码如下:


    process( USER_CLK )
    begin
        if(USER_CLK'event and USER_CLK = '1') then
            if((SYSTEM_RESET='1') or (tx_data_bram_i = X"ff"))then
                tx_data_bram_i <= (others => '0') after DLY;
      tx_charisk_i   <= (others => '0') after DLY;
            else
                tx_data_bram_i <= tx_data_bram_i + 1 after DLY;
      tx_charisk_i   <= (others => '0') after DLY;
      if(tx_data_bram_i = X"1a") then
         tx_charisk_i <= (others => '1') after DLY;
      end if;
            end if;
        end if;
    end process;



    process( USER_CLK )
    begin
        if(USER_CLK'event and USER_CLK = '1') then
            if(SYSTEM_RESET='1') then
                TX_DATA      <= (others => '0') after DLY;
            else
                TX_DATA      <= (tied_to_ground_vec_i(7 downto 0) & tx_data_bram_i) after DLY;
            end if;
        end if;
    end process;



    process( USER_CLK )
    begin
        if(USER_CLK'event and USER_CLK = '1') then
            if(SYSTEM_RESET='1') then
                TX_CHARISK    <= (others => '0') after DLY;
            else
                TX_CHARISK    <= tx_charisk_i after DLY;
            end if;
        end if;
    end process;


我发送的数据是1到255,周期发送,其实就是锯齿波。这个模块的关键就是理解TX_CHARISK的含义,手册上的解释是指示发送的是K字符。8B/10B编码可以分为256个数据字符和12个控制字符。数据字符,标为D,用于传输数据;控制字符,标为K,用于传输控制序列。12个控制字符用于对齐、控制,以及将带宽划分为子通道。 在向导中设置comma value时,我选择了userdefined,程序中每当出现1C时也就是K28.0,就将TX_CHARISK置高。开始时我没注意这个问题,导致数据接受总是出错。


        至此,我已完成了发送和接受自己产生的数据。今后我将完成以下工作:


1、延长SATA数据传输线并人为地加入干扰,观察数据的误码率;


2、由于现有8B/10B编码效率只有80%,考虑改用其他编码以提高效率;


3、实现两个实验板的数据传输,并观察数据的误码率。


GO,GO,加油!

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条