RGMII_PHY測試筆記1 基於開發板MiS603-X25
作者:湯金元
日期:20150817
公司:南京米聯電子科技有限公司
博客:http://blog.chinaaet.com/detail/46639
論壇:www.osrc.cn
網店:http://osrc.taobao.com
網絡通信對於本人來說一直很神秘,沒有搞過10M網絡,也沒有搞過100M網絡,更沒有搞過千兆網絡,更不要說RGMII了。但是今天本人成功了,實現0到RGMII突破。如果,兄弟你覺得有難度,我告訴你,你也行的,下面就開始見證本人徒步學習RGMII千兆網絡部分的苦逼經歷。今天主要完成PHY的測試。
何為RGMII ?
RGMII(Reduced Gigabit Media Independent Interface)是Reduced GMII(吉比特介質獨立接口)。RGMII均采用4位數據接口,工作時鍾125MHz,並且在上升沿和下降沿同時傳輸數據,因此傳輸速率可達1000Mbps。同時兼容MII所規定的10/100 Mbps工作方式,支持傳輸速率:10M/100M/1000Mb/s ,其對應clk 信號分別為:2.5MHz/25MHz/125MHz。RGMII數據結構符合IEEE以太網標准,接口定義見IEEE 802.3-2000。
采用RGMII的目的是降低電路成本,使實現這種接口的器件的引腳數從25個減少到14個。
RGMII接口定義?
發送器:
◎ GTX_CLK——吉比特TX..信號的時鍾信號(125MHz)
◎ TXD[3..0]——被發送數據
◎ TX_CTL——發送控制
注:在千兆速率下,向PHY提供GTX_CLK信號,TXD、TXEN、TXER信號與此時鍾信號同步。否則,在10/100M速率下,PHY提供 TXCLK時鍾信號,其它信號與此信號同步。其工作頻率為25MHz(100M網絡)或2.5MHz(10M網絡)。
接收器:
◎ RX_CLK——接收時鍾信號(從收到的數據中提取,因此與GTXCLK無關聯)
◎ RXD[3..0]——接收數據
◎ RX_CTL——接收控制
◎ COL——沖突檢測(僅用於半雙工狀態)
◎ CRS——載波監聽
管理配置(控制和狀態信息):
◎ MDC——配置接口時鍾
◎ MDIO——配置接口I/O
RGMII接口相對於GMII接口,在TXD和RXD上總共減少8根數據線。
RGMII通信時序?
發送器:
◎ TX_CLK
吉比特TX..信號的時鍾信號(125MHz)
◎ TXD[3..0]
發送數據
TX_CLK高電平輸出數據低4位,低電平輸出數據高四位。
◎ TX_CTL
—發送控制
TX_CLK高電平期間為1表示發送使能,TX_CLK低電平期間為1表示發送正確
接收器:
◎ RX_CLK
吉比特RX..信號的時鍾信號(125MHz)
◎ RXD[3..0]
接收數據
RX_CLK高電平接收數據低4位,低電平接收數據高四位。
◎ RX_CTL
—接收控制
RX_CLK高電平期間為1表示接收使能,RX_CLK低電平期間為1表示接收正確
TX_CTL和RX_CTL是數據同步機制,可以理解為同步信號
RGMII 硬件方案-VSC8601
VITESSE公司的VSC8601是一顆支持10/100/1000M PHY的RGMII MAC接口芯片,此芯片價格便宜,淘寶價格大概十幾元一顆,另外封裝是TQFP64 封裝,只有64個PIN外圍簡單,焊接調試方便,功耗低,支持3.3V的IO接口,算是RGMII方案中首選無二的IC了。
VSC8601應用方案
RGMII 硬件接口
硬件電路原理圖
由於時鍾速度125MHZ 雙邊沿采樣,對硬件要求很高,PCB必須等長布線
好了,具備這些硬件知識就可以設計程序了。
一下本人把一些設計要點列出來,讀者具體看程序
1、產生至少1MS 復位信號,如果沒有產生這個信號,那么PHY芯片不會工作
//generate PHY reset signal
reg[22:0]rgmii_rst_cnt=0;
assign rgmii_rst_n_o=rgmii_rst_cnt[22];
always @(posedge CLK_50MHZ_i)begin
if(!rgmii_rst_cnt[22])rgmii_rst_cnt<=rgmii_rst_cnt+1'b1;
End
2、為了實現上下沿都進行采樣,關於一些原語的基礎知識
ILOGIC2資源
圖ILOGIC2邏輯框圖,它可支持以下功能。
邊沿觸發D型觸發器。
IDDR(NONE、C0或C1)模式。
鎖存器。
異步/組合邏輯。
(1) 異步/組合邏輯。
當有下列情況之一時,軟件會自動生成組合通路,使輸入驅動器與FPGA內部邏輯資源直接連接。
FPGA的輸入數據與內部邏輯直接相連,而沒有用寄存器。
“打包I/O寄存器/鎖存器到IOB中”的屬性設置為OFF。
(2) IDDR模式。
Spartan-6器件的ILOGIC2中有專用寄存器來實現輸入雙倍數據速率(DDR)寄存器。可以通過例化IDDR2的原語來使用此功能。
DDR2的屬性DDR_ALIGNMENT有3種模式:NONE、C0和C1。
在NONE模式下,輸入DDR時序如圖2-40所示。寄存器在C0上升沿將輸入數據D寄存到Q0,C1上升沿將下一輸入數據D寄存到Q1。
圖2-40 DDR_ALIGNMENT=NONE時輸入DDR時序示意圖
在某些情況下,輸入數據必須同步到一個時鍾域里,通常C0同步。但是在頻率比較高的情況下,這種同步相對比較困難,因為有效時間僅為時鍾周期的一半(50%占空比的情況下)。Spartan-6器件中的IDDR2包含了專用的邏輯,可以在ILOGIC2內部進行時鍾域的同步。
當DDR_ALIGNMENT為C0(或C1),信號Q0(Q1)在C1(C0)再次寄存,通過內部互聯將輸入數據同步到同一時鍾域。時序圖如圖2-41所示。
圖2-41 DDR_ALIGNMENT=C0\C1 的輸入DDR
IDDR 的原語如圖2-42 所示。
圖2-42 IDDR2 的原語
OLOGIC2 資源
如圖2-43所示,OLOGIC2主要由兩部分組成,分別是輸出數據路徑和三態控制路徑。
這兩個部分可以配置成以下模式。
邊沿觸發D 型觸發器。
DDR 模式(NONE、C0 或C1 同步方式)。
電平敏感鎖存器。
異步/組合邏輯。
圖2-43 OLOGIC2 邏輯模塊
(1) 組合數據輸出和三態控制路徑。
當有下列情況之一時,軟件會自動生成組合通路,將FPGA 內部數據直接輸出到輸出驅動器或驅動器的控制端。
“打包I/O 寄存器/鎖存器到IOB 中”的屬性設置為OFF。
(2) ODDR模式。
Spartan-6器件的OLOGIC2中具有專用寄存器,用來實現DDR輸出寄存器。例化ODDR2原語可以使用此功能。當使用OLOGIC2時,會自動使用多路復用器,多路復用器的控制端產生於時鍾信號,不需要手動控制。ODDR2 有兩個時鍾輸入,相位差180°。
ODDR2 支持以下操作模式。
NONE 模式:允許設計人員在C0 和C1 時鍾的上升沿將兩個數據通過DDR多路復用器送
至輸出引腳,如圖2-44所示。·
圖2-44 DDR_ALIGNMENT=NONE 下的ODDR2
C0模式:在時鍾C0上升沿時,將兩個數據通過DDR多路復用器送至輸出引腳。
C1模式:在時鍾C1上升沿時,將兩個數據通過DDR多路復用器送至輸出引腳。
ODDR原語如圖2-45所示。
圖2-45 ODDR原語
原語應用-雙邊沿采樣
//use IDDR2 sample data with poseadge and negadge
IDDR2 #(
.DDR_ALIGNMENT("C0"),
.INIT_Q0(1'b0),
.INIT_Q1(1'b0),
.SRTYPE("SYNC")
)
Iddr2_0(
.Q0(gmii_rxd[4]), // 1-bit output captured with C0 clock
.Q1(gmii_rxd[0]), // 1-bit output captured with C1 clock
.C0(rgmii_rxclk_n), // 1-bit clock input
.C1(rgmii_rxclk_i), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D(rgmii_rxd_i[0]), // 1-bit ddr data input
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
原語應用雙邊沿輸出
//usb ODDR2 output data with posadge and neadge
assign rgmii_txdv_o = gmii_txdv;
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
)
ODDR2_0 (
.Q(rgmii_txd_o[0]), // 1-bit DDR output data
.C0(rgmii_txclk), // 1-bit clock input
.C1(rgmii_txclk_n), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(gmii_txd[0]), // 1-bit data input (associated with C0)
.D1(gmii_txd[4]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
為了實現數據的發送和接收的對比需要准備2塊MIS603開發板
測試數據發送:
原理:發送數據從0~255 不停循環
//計數器循環累加,當gmii_txdv_cnt[8]為0時將數據輸出
reg [8:0]gmii_txdv_cnt;
assign gmii_txd_ts = gmii_txdv_cnt[8] ? 7'd0 : gmii_txdv_cnt[7:0];
//數據有效標志
assign gmii_txdv_ts = ((~gmii_txdv_cnt[8])||(gmii_txdv_cnt==256)||(gmii_txdv_cnt==257)) ? 1'b1 : 1'b0;
//循環計數器
always @(posedge rgmii_txclk_ts)
if(~rst_n)begin
gmii_txdv_cnt <= 9'd0;
end
else begin
gmii_txdv_cnt <= gmii_txdv_cnt +1'b1;
end
測試數據接收對比:
原來采用了一個狀態機首先識別0x55 識別2個0x55后,后面就是有效數據,如果是從0~255不停累加就代表正確。
reg [7:0]gmii_rxd_next;
//比較數據
assign rxd_error= (rxd_s==2'd2) ? ((gmii_rxd_next==gmii_rxd_ts) ? 1'b0 : 1'b1 ) : 1'b0;
reg [1:0] rxd_s;
//下一個數據被比較數據准備
always @(posedge rgmii_rxclk_ts)begin
if((~rst_n)||(gmii_rxdv_ts!=2'b11))begin
gmii_rxd_next<=8'd1;
rxd_s<=2'd0;
end
else if(gmii_rxdv_ts==2'b11)begin
case(rxd_s)
0:
if(gmii_rxd_ts==8'h55)//接收第一個55
rxd_s <= rxd_s + 1'b1;//0x55
1:
if(gmii_rxd_ts==8'h55)//接收第二個55
rxd_s <= rxd_s + 1'b1;
else
rxd_s <= 2'd0;
2: begin //計算下一個比較數據
gmii_rxd_next <= gmii_rxd_ts+1'b1;
if(gmii_rxd_ts==8'd255)
rxd_s <= 2'd0;
end
endcase
end
end
測試結果:
PHY板對板測試,48小時以上沒有任何錯誤。
源碼下載地址:
http://pan.baidu.com/s/1pwSnc