终于有时间写日志了,这几周还真是忙啊,呵呵!
高速数据传输方面有了新的进展。我将向导生成的例子从头到尾研究了几遍,发现它包含以下几个模块: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,加油!
文章评论(0条评论)
登录后参与讨论