之前介紹MII接口時,有介紹過RGMII接口的由來,下面在貼一下:
表8?7 MII接口介紹
RGMII是GMII的簡化版本,發送端信號:TXD[3:0]、 TX_CLK、TX_EN,接收端信號:RX_DV、RXD[3:0]、RX_CLK,當Clock=125MHz,數據位寬4bit(一個時鐘周期里,上升沿取TXRX的0-3bit,下降沿取TXRX的4-7bit,所以實際還是在一個時鐘周期里傳輸8bit數據),1000Mbps=125 MHz *8bit、100Mbps=25 MHz *8bit、10Mbps=2.5MHz *8bit。
其實從實現方式看,很容易看出RGMII傳輸/收取數據的方式和DDR的方式類似,所以下面會針對這方面詳細介紹。8.5.1.1 RGMII信號定義及時序RGMII 使用 4bit 數據接口采用上下沿 DDR( Double Data Rate)的方式在一個時鐘周期之內傳輸 8bit數據信號,即上升沿發送或接收數據的低 4 位[3:0],下降沿發送或接收數據的高 4 位[7:4]。
發送端:
TXC:發送數據信號和控制信號對應的同步時鐘信號( 125M、 25M、 2.5M)
TXD[3:0]:發送數據信號, 4bit 位寬
TX_CTL:發送控制信號
發送端信號時序如下圖所示。
圖8?18 RGMII發送端信號時序(來源88E1512datasheet,下同)
一般的 PHY 芯片都支持兩種 RGMII 發送端口的時序關系。一種稱為非延時模式,如下圖所示:
圖8?19 RGMII發送端非延時模式(來源88E1512datasheet,下同)
即要滿足時鐘信號 TXC 的邊沿對準數據信號 TXD[3:0]和控制信號 TX_CTL 有效窗口中心附近的位置,也就是說 TXC 比其他信號存在 2ns( 90°相位)(2ns來源:當 RGMII 接口工作于 1000M 速率時, TXC 和RXC 時鐘信號都為 125MHz,那么單個接口的數據率便等同于 250Mbps,單個信號的有效數據窗最大為 4ns。)左右的延時。
另一種為延時模式,如下圖所示。
圖8?20 RGMII發送端延時模式(來源88E1512datasheet,下同)
這種時序要求 TXC 的邊沿不其發送的數據 TXD 和控制信號 TX_CTL 邊沿對齊,所有信號具有相同的相位。
一般來說,大部分 PHY 芯片默認都是采用正常時序模式,可通過 MDIO 接口設置寄存器,或者芯片特殊功能引腳將其配置為延時模式。
接收端:
RXC:接收數據信號和控制信號對應的同步時鐘信號( 125M、 25M、 2.5M)
RXD[3:0]:接收數據信號,4bit 位寬
RX_CTL:接收控制信號
接收端信號的時序如下圖所示。
圖8?21 RGMII接收端信號時序
同理接收端也有非延時和延時模式,原理同上,時序圖如下。
圖8?22 RGMII接收端非延時模式(來源88E1512datasheet,下同)
圖8?23 RGMII接收端延時模式(來源88E1512datasheet,下同)
8.5.1.2 RGMII時序中的原語使用在 FPGA 中設計高速源同步接口的重點在于時序控制和時序約束。
在 7 系列 FPGA 中實現 RGMII 接口需要借助 5 種原語,分別是:IDDR、 ODDR、 IDELAYE2、ODELAYE2(A7 中沒有)、 IDELAYCTRL。
其中, IDDR 和 ODDR 分別是輸入和輸出的雙邊沿寄存器,位于 IOB 中。IDELAYE2 和ODELAYE2,分別用于控制 IO 口輸入和輸出延時。同時, IDELAYE2 和 ODELAYE2 的延時值需要使用原語 IDELAYCTRL 來進行校準。另外,需要注意的是,在 7 系列器件的 HR Bank 中沒有ODELAYE2,只有在 HP BANK 中才有 ODELAYE2。
上述幾個原語在Xilinx中屬于I/O計算組件,其他常見的原語如下:
表8?8 I/O端口組件
下面針對即將使用的幾個原語進行介紹(摘選自米聯客教程,在此謝過):
( 1) IDDR
IDDR 將輸入的雙邊沿 DDR 信號,在輸出端恢復為兩個并行單邊沿 SDR 信號。IDDR 的原語如下。詳細參數可參考 UG471。
代碼8?1 IDDR 的原語
1.// IDDR : In order to incorporate this function into the design,
2.// Verilog : the following instance declaration needs to be placed
3.// instance : in the body of the design code. The instance name
4.// declaration : (IDDR_inst) and/or the port declarations within the
5.// code : parenthesis may be changed to properly reference and
6.// : connect this function to the design. Delete or comment
7.// : out inputs/outs that are not necessary.
8.
9.// 《-----cut code=“” below=“” this=“” line----=“”》
10.
11. // IDDR: Input Double Data Rate Input Register with Set, Reset
12. // and Clock Enable.
13. // Artix-7
14. // Xilinx HDL Language Template, version 2018.3
15.
16. IDDR #(
17. .DDR_CLK_EDGE(“OPPOSITE_EDGE”), // “OPPOSITE_EDGE”, “SAME_EDGE”
18. // or “SAME_EDGE_PIPELINED”
19. .INIT_Q1(1‘b0), // Initial value of Q1: 1’b0 or 1‘b1
20. .INIT_Q2(1’b0), // Initial value of Q2: 1‘b0 or 1’b1
21. .SRTYPE(“SYNC”) // Set/Reset type: “SYNC” or “ASYNC”
22. ) IDDR_inst (
23. .Q1(Q1), // 1-bit output for positive edge of clock
24. .Q2(Q2), // 1-bit output for negative edge of clock
25. .C(C), // 1-bit clock input
26. .CE(CE), // 1-bit clock enable input
27. .D(D), // 1-bit DDR data input
28. .R(R), // 1-bit reset
29. .S(S) // 1-bit set
30. );
31.
32. // End of IDDR_inst instantiation
33.
34.
C 為同步時鐘, Q1 和 Q2 則是分別與 C 上升沿和下降沿同步的輸出的 SDR 數據, D 為 DDR 輸入。參數 DDR_CLK_EDGE 用來決定了 C、 Q1、 Q2 和 D 之間的時序關系。DDR_CLK_EDGE 有 3 種模式:OPPOSITE_EDGE、 SAME_EDGE 以及 SAME_EDGE_PIPELINED,3 種時序關系如下圖所示。
圖8?24 DDR_CLK_EDGE 3 種模式(來源UG741)
(2) ODDR
使用 ODDR 將 TXC 同一個時鐘周期內的兩個 SDR 信號分別通過上升沿和下降沿輸出為 DDR 信號。ODDR 的原語如下,詳細參數可參考 UG471。
代碼8?2 ODDR原語
1.// ODDR : In order to incorporate this function into the design,
2.// Verilog : the following instance declaration needs to be placed
3.// instance : in the body of the design code. The instance name
4.// declaration : (ODDR_inst) and/or the port declarations within the
5.// code : parenthesis may be changed to properly reference and
6.// : connect this function to the design. Delete or comment
7.// : out inputs/outs that are not necessary.
8.
9.// 《-----cut code=“” below=“” this=“” line----=“”》
10.
11. // ODDR: Output Double Data Rate Output Register with Set, Reset
12. // and Clock Enable.
13. // Artix-7
14. // Xilinx HDL Language Template, version 2018.3
15.
16. ODDR #(
17. .DDR_CLK_EDGE(“OPPOSITE_EDGE”), // “OPPOSITE_EDGE” or “SAME_EDGE”
18. .INIT(1‘b0), // Initial value of Q: 1’b0 or 1‘b1
19. .SRTYPE(“SYNC”) // Set/Reset type: “SYNC” or “ASYNC”
20. ) ODDR_inst (
21. .Q(Q), // 1-bit DDR output
22. .C(C), // 1-bit clock input
23. .CE(CE), // 1-bit clock enable input
24. .D1(D1), // 1-bit data input (positive edge)
25. .D2(D2), // 1-bit data input (negative edge)
26. .R(R), // 1-bit reset
27. .S(S) // 1-bit set
28. );
29.
30. // End of ODDR_inst instantiation
31.
32.
DDR_CLK_EDGE 有兩種模式: OPPOSITE_EDGE 和 SAME_EDGE,兩種時序關系如下圖所示。
圖8?25 DDR_CLK_EDGE兩種模式
對于 OPPOSITE_EDGE 模式,在 FPGA 內部也同樣需要兩個反相時鐘來同步 D1 和 D2,較少使用。在設計 RGMII 接口時使用了 SAME_EDGE 模式。
(3) IDELAYE2
IDELAYE2 用于在信號通過引腳進入芯片內部之前,進行延時調節。這里給出本方案中的用法,原語描述如下。詳細參數可參考 UG471。
代碼8?3 IDELAYE2 原語
1.// IDELAYE2 : In order to incorporate this function into the design,
2.// Verilog : the following instance declaration needs to be placed
3.// instance : in the body of the design code. The instance name
4.// declaration : (IDELAYE2_inst) and/or the port declarations within the
5.// code : parenthesis may be changed to properly reference and
6.// : connect this function to the design. All inputs
7.// : and outputs must be connected.
8.
9.// 《-----cut code=“” below=“” this=“” line----=“”》
10.
11. // IDELAYE2: Input Fixed or Variable Delay Element
12. // Artix-7
13. // Xilinx HDL Language Template, version 2018.3
14.
15. (* IODELAY_GROUP = *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
16.
17. IDELAYE2 #(
18. .CINVCTRL_SEL(“FALSE”), // Enable dynamic clock inversion (FALSE, TRUE)
19. .DELAY_SRC(“IDATAIN”), // Delay input (IDATAIN, DATAIN)
20. .HIGH_PERFORMANCE_MODE(“FALSE”), // Reduced jitter (“TRUE”), Reduced power (“FALSE”)
21. .IDELAY_TYPE(“FIXED”), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
22. .IDELAY_VALUE(0), // Input delay tap setting (0-31)
23. .PIPE_SEL(“FALSE”), // Select pipelined mode, FALSE, TRUE
24. .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0)。
25. .SIGNAL_PATTERN(“DATA”) // DATA, CLOCK input signal
26. )
27. IDELAYE2_inst (
28. .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output
29. .DATAOUT(DATAOUT), // 1-bit output: Delayed data output
30. .C(C), // 1-bit input: Clock input
31. .CE(CE), // 1-bit input: Active high enable increment/decrement input
32. .CINVCTRL(CINVCTRL), // 1-bit input: Dynamic clock inversion input
33. .CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input
34. .DATAIN(DATAIN), // 1-bit input: Internal delay data input
35. .IDATAIN(IDATAIN), // 1-bit input: Data input from the I/O
36. .INC(INC), // 1-bit input: Increment / Decrement tap delay input
37. .LD(LD), // 1-bit input: Load IDELAY_VALUE input
38. .LDPIPEEN(LDPIPEEN), // 1-bit input: Enable PIPELINE register to load data input
39. .REGRST(REGRST) // 1-bit input: Active-high reset tap-delay input
40. );
41.
42. // End of IDELAYE2_inst instantiation
43.
44.
(4) ODELAYE2
ODELAYE2原語如下,更多詳細信息可參考 UG471。
代碼8?4 ODELAYE2原語1.// ODELAYE2 : In order to incorporate this function into the design,
2.// Verilog : the following instance declaration needs to be placed
3.// instance : in the body of the design code. The instance name
4.// declaration : (ODELAYE2_inst) and/or the port declarations within the
5.// code : parenthesis may be changed to properly reference and
6.// : connect this function to the design. All inputs
7.// : and outputs must be connected.
8.
9.// 《-----cut code=“” below=“” this=“” line----=“”》
10.
11. // ODELAYE2: Output Fixed or Variable Delay Element
12. // Kintex-7
13. // Xilinx HDL Language Template, version 2018.3
14.
15. (* IODELAY_GROUP = *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
16.
17. ODELAYE2 #(
18. .CINVCTRL_SEL(“FALSE”), // Enable dynamic clock inversion (FALSE, TRUE)
19. .DELAY_SRC(“ODATAIN”), // Delay input (ODATAIN, CLKIN)
20. .HIGH_PERFORMANCE_MODE(“FALSE”), // Reduced jitter (“TRUE”), Reduced power (“FALSE”)
21. .ODELAY_TYPE(“FIXED”), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
22. .ODELAY_VALUE(0), // Output delay tap setting (0-31)
23. .PIPE_SEL(“FALSE”), // Select pipelined mode, FALSE, TRUE
24. .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0)。
25. .SIGNAL_PATTERN(“DATA”) // DATA, CLOCK input signal
26. )
27. ODELAYE2_inst (
28. .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output
29. .DATAOUT(DATAOUT), // 1-bit output: Delayed data/clock output
30. .C(C), // 1-bit input: Clock input
31. .CE(CE), // 1-bit input: Active high enable increment/decrement input
32. .CINVCTRL(CINVCTRL), // 1-bit input: Dynamic clock inversion input
33. .CLKIN(CLKIN), // 1-bit input: Clock delay input
34. .CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input
35. .INC(INC), // 1-bit input: Increment / Decrement tap delay input
36. .LD(LD), // 1-bit input: Loads ODELAY_VALUE tap delay in VARIABLE mode, in VAR_LOAD or
37. // VAR_LOAD_PIPE mode, loads the value of CNTVALUEIN
38.
39. .LDPIPEEN(LDPIPEEN), // 1-bit input: Enables the pipeline register to load data
40. .ODATAIN(ODATAIN), // 1-bit input: Output delay data input
41. .REGRST(REGRST) // 1-bit input: Active-high reset tap-delay input
42. );
43.
44. // End of ODELAYE2_inst instantiation
45.
46.
(5) IDELAYCTRL
IDELAY2 和 ODELAY2 都需要 IDELAYCTRL 來進行校準。IDELAYCTRL 原語如下。更多詳細信息可參考 UG471。
代碼8?5 IDELAYCTRL 原語
1.// IDELAYCTRL : In order to incorporate this function into the design,
2.// Verilog : the following instance declaration needs to be placed
3.// instance : in the body of the design code. The instance name
4.// declaration : (IDELAYCTRL_inst) and/or the port declarations within the
5.// code : parenthesis may be changed to properly reference and
6.// : connect this function to the design. All inputs
7.// : and outputs must be connected.
8.
9.// 《-----cut code=“” below=“” this=“” line----=“”》
10.
11. // IDELAYCTRL: IDELAYE2/ODELAYE2 Tap Delay Value Control
12. // Artix-7
13. // Xilinx HDL Language Template, version 2018.3
14.
15. (* IODELAY_GROUP = *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
16.
17. IDELAYCTRL IDELAYCTRL_inst (
18. .RDY(RDY), // 1-bit output: Ready output
19. .REFCLK(REFCLK), // 1-bit input: Reference clock input
20. .RST(RST) // 1-bit input: Active high reset input
21. );
22.
23. // End of IDELAYCTRL_inst instantiation
24.
25.
IDELAYCTRL 需要一個參考時鐘信號 REFCLK 來校準 IDELAY2 和 ODELAY2 每個 tap 的延時值,可用的 REFCLK 頻率為 200M、 300M、 400M。時鐘越高對應的 tap 延時平均值越小,也就是說延時調節精度越高。DS182 中對此有如下描述。
大部分情冴下使用 200M 的參考時鐘就可以滿足實際需求。
8.5.1.3 RGMII發送接口設計
(1) PHY RGMII 發送接口時序
相關的時序在上面已經介紹,主要關注tsetup、thold 默認模式具體如下:
(2)設計方案
針對上述時序關系, RGMII 發送接口的設計方案如下圖所示。
圖8?27 RGMII 發送接口的設計方案
(3)時序約束
針對 RGMII 發送接口需要進行 output delay 約束,如下所示。使用 MMCM 輸出的時鐘 phy_tx_clk 作為所有 ODDR 的輸入時鐘。這里以 1 個 RGMII 接口為例。
代碼8?6 時序約束
1.settx_clk [get_clocks -include_generated_clocks -of [get_pins clk_wiz_0/inst/mmcm_adv_inst/CLKOUT1]]
2.create_generated_clock -name phy_tx_clk -source [get_pins clk_wiz_0/inst/mmcm_adv_inst/CLKOUT1] -multiply_by1 [get_ports phy1_rgmii_tx_clk]
3.set_output_delay -clock [get_clocksphy_tx_clk] -max -0.900 [get_ports {phy1_rgmii_tx_ctl phy1_rgmii_tx_data[*]}}]
4.set_output_delay -clock [get_clocksphy_tx_clk] -min -2.900 [get_ports {phy1_rgmii_tx_ctl {phy1_rgmii_tx_data[*]}}]
5.set_output_delay -clock [get_clocksphy_tx_clk] -max -0.900 [get_ports {phy1_rgmii_tx_ctl {phy1_rgmii_tx_data[*]}}] -clock_fall -
6.add_delay
7.set_output_delay -clock [get_clocksphy_tx_clk] -min -2.900 [get_ports {phy1_rgmii_tx_ctl {phy1_rgmii_tx_data[*]}}] -clock_fall -add_delay
由于時序分析中存在 2 個時鐘 phy_tx_clk 和 tx_clk,這兩個時鐘在物理上實際是同 1 個時鐘,都是由MMCM 同 1 個引腳輸出的。但是時序分析工具會把它們當做 2 個不同的時鐘而進行跨時鐘域分析。因此,需要剔除這 2 個時鐘之間的一些虛假路徑,避免時序報錯。
針對本文檔的設計方法,RGMII 發送接口 DDR 的 setup time 分析是從 rise 到 rise,或者 fall 到 fall。因此需要剔除 rise 到 fall 和 fall 到 rise 的 setup time 偽路徑。同理, hold time 分析是從 rise 到 fall 或fall 到 rise,因此需要剔除 rise 到 rise 和 fall 到 fall 的 hold time 偽路徑。如下所示:
1.set_false_path -fall_from $tx_clk -rise_to [get_clocksphy_tx_clk] -setup
2.set_false_path -rise_from $tx_clk -fall_to [get_clocksphy_tx_clk] -setup
3.set_false_path -fall_from $tx_clk -fall_to [get_clocksphy_tx_clk] -hold
4.set_false_path -rise_from $tx_clk -rise_to [get_clocksphy_tx_clk] -hold
除此之外,由于 setup time 分析是從 rise 到 rise 或fall 到 fall 的。為了避免時序分析工具對 2 個時鐘phy_tx_clk 和 tx_clk 之間 setup time 進行錯誤的多周期分析,需要進行如下約束。
1.set_multicycle_path 0 -setup -end -rise_from $tx_clk -rise_to [get_clocksphy_tx_clk]
2.set_multicycle_path 0 -setup -end -fall_from $tx_clk -fall_to [get_clocksphy_tx_clk]
8.5.1.4 RGMII接收接口設計
(1) PHY RGMII 接收接口時序
相關的時序在上面已經介紹,主要關注tsetup、thold 默認模式具體如下:
(2)設計方案
針對上述時序關系, RGMII 接收接口的設計方案如下圖所示。通過 FPGA 引腳輸入的時鐘 RXC 經過BUFIO 可以通過最短的延時接入 IDDR 中。另外,輸入時鐘經過 BUFG 或者 BUFR 進入 FPGA 內部時鐘網絡供內部邏輯所使用。BUFR 僅局限于單個 clock region 內部的邏輯資源,如果邏輯規模較大,建議使用 BUFG。
圖8?30 RGMII 接收接口的設計方案
(3)時序約束
針對 RGMII 接收接口需要進行 intput delay 約束,如下所示。使用 PHY 芯片輸入時鐘作為所有 IDDR的輸入時鐘。這里以 1 個 RGMII 接口為例。
1.create_clock -period 6.000 -name phy1_rx_clk [get_ports phy1_rgmii_rx_clk]
2.set_input_delay -clock [get_clocks phy1_rx_clk] -max 2.800 [get_ports {{phy1_rgmii_rx_data[*]} phy1_rgmii_rx_ctl}]
3.set_input_delay -clock [get_clocks phy1_rx_clk] -min 1.200 [get_ports {{phy1_rgmii_rx_data[*]} phy1_rgmii_rx_ctl}]
4.set_input_delay -clock [get_clocks phy1_rx_clk] -clock_fall -max -add_delay 2.800 [get_ports {{phy1_rgmii_rx_data[*]} phy1_rgmii_rx_ctl}]
5.set_input_delay -clock [get_clocks phy1_rx_clk] -clock_fall -min -add_delay 1.200 [get_ports {{phy1_rgmii_rx_data[*]} phy1_rgmii_rx_ctl}]
除此之外,還需要將所有 IDELAYE2 和 IDELAYCTRL 約束到一個 group 中。在 7 系列器件中, 1 個BANK 對應一個 clock region,每個 clock region 對應 1 個 IDELAYCTRL。FPGA中有 4 組 RGMII 接收接口,分布在 BANK13 和 BANK14 中。因此,需要分 2 個 group 進行約束,約束如下。
1.set_property IODELAY_GROUP iodelay_grp_bank13 [get_cells {idelayctrl_inst1 rgmii_receive_module1/delay_rgmii_rx_ctl
2.{rgmii_receive_module1/RGMII_RX_DATA_BUS[*].delay_rgmii_rxd}}]
3.set_property IODELAY_GROUP iodelay_grp_bank13 [get_cells {rgmii_receive_module2/delay_rgmii_rx_ctl
4.{rgmii_receive_module2/RGMII_RX_DATA_BUS[*].delay_rgmii_rxd}}]
5.set_property IODELAY_GROUP iodelay_grp_bank14 [get_cells {idelayctrl_inst2 rgmii_receive_module3/delay_rgmii_rx_ctl
6.{rgmii_receive_module3/RGMII_RX_DATA_BUS[*].delay_rgmii_rxd}}]
7.set_property IODELAY_GROUP iodelay_grp_bank14 [get_cells {rgmii_receive_module4/delay_rgmii_rx_ctl
8.{rgmii_receive_module4/RGMII_RX_DATA_BUS[*].delay_rgmii_rxd}}]
另外,約束每組 RGMII 接收接口的 IDELAYE2 的延時 tap 數,經嘗試最佳 tap 為 14。如下所示。
1.set_property IDELAY_VALUE 14 [get_cells rgmii_receive_module1/delay_rgmii_rx_ctl] 2.set_property IDELAY_VALUE 14 [get_cells {rgmii_receive_module1/RGMII_RX_DATA_BUS[*].delay_rgmii_rxd}]
編輯:jq
-
芯片
+關注
關注
455文章
50732瀏覽量
423247 -
RMII
+關注
關注
0文章
8瀏覽量
12057 -
MII
+關注
關注
0文章
5瀏覽量
6032
原文標題:基于原語的千兆以太網RGMII接口設計
文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術江湖】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論