t27.aiEnglish

Тайминг RGMII

Вы узнаете

Что тайминг RGMII требует от полубайта на двух фронтах и что спека о нём утверждает.

RGMII переносит полубайт за фронт такта, на обоих фронтах: двойная скорость данных на 125 МГц для гигабита и одинарная для 10 и 100. Спека этого урока, написанная для этого курса, несёт тайминговую арифметику и свои допущения в заголовке. Запись прогоняет t27c по ней.

Попробовать

В записи проследите прогон; затем в спеке найдите частоту DDR и что спека говорит о понижении до 10 и 100.

Открыть интерактивный урок →

t27c on rgmii.t27 -- RGMII timing, native
t27c on rgmii.t27 -- RGMII timing, native ↗

t27c test-report on the RGMII spec: 7 tests pass natively plus one comptime invariant -- the 8 ns gigabit period, a nibble on both edges, the 78 ps tap ladder.

specs/fpga/rgmii.t27

// SPDX-License-Identifier: Apache-2.0
; rgmii.t27 -- RGMII v2.0 timing arithmetic, as one spec.
; The reduced gigabit media-independent interface: 4 data bits, both clock
; edges, 125 MHz -- 1000 Mbps over 12 pins. This spec owns the arithmetic a
; design applies when it reasons about RGMII: periods, bit times, downshift
; rates, and how many IDELAY taps a skew budget needs.
; ----
; SOURCE:
;   RGMII specification v2.0 (HP, April 2002)   DDR data, 125 MHz TXC,
;       internal-delay option (RGMII-ID), 10/100 downshift
;   Xilinx UG471 (7 Series SelectIO)            IDELAYE2 tap resolution
;       = 1 / (32 x 2 x f_REF): 78 ps at the 200 MHz reference, 31 taps
;   Xilinx UG471                                  ODELAYE2 exists in HP
;       banks only; Artix-7 has HR banks, so no output delay element
; ORACLE: the constants are cited above; every other number in this file is
; derived by the test blocks below from those constants -- no figure is
; transcribed from memory. (U64 widening for the 1e12 ps-per-second product
; follows the simulator.t27 idiom.)
; ----
; THEORETICAL: no RGMII board measurement backs this spec yet (no rgmii run
; exists on the bench -- checked 2026-10-08). Course pages built on it must
; say the numbers are theoretical until a board run lands. Board PHYs differ
; (Wukong xc7a200tfgg676 vs AX7203 xc7a200tfbg484); name the board.
; ----
; Course use: trinity buses-and-peripherals module 8, lessons rgmii and
; idelay-and-odelay (gHashTag/trinity#1484).

module fpga_rgmii;

; --- The interface, straight from the spec sheet ---------------------------

pub const RGMII_CLOCK_HZ   : u32 = 125_000_000;
; one nibble per DDR phase
pub const RGMII_DATA_BITS  : u32 = 4;
; data on both clock edges
pub const RGMII_EDGES      : u32 = 2;
pub const RGMII_IDEAL_MBPS : u32 = 1000;

; 10/100 downshift: same pins, slower clock (RGMII v2.0 1000/100/10)
pub const RGMII_100_HZ     : u32 = 25_000_000;
pub const RGMII_10_HZ      : u32 = 2_500_000;

; --- Xilinx 7-series delay elements (UG471) --------------------------------

pub const IDELAY_REF_HZ    : u32 = 200_000_000;
pub const IDELAY_TAPS      : u32 = 31;
; Artix-7 = HR banks only (UG471)
pub const HAVE_ODELAY      : bool = false;

; ps per tap = 1e12 / (32 * 2 * f_REF). The 1e12 product needs u64 (the
; simulator.t27 ns arithmetic hits the same wall); the result fits u32.
pub fn tap_resolution_ps(ref_hz : u32) u32 {
    return ((1_000_000_000_000 as u64) / ((32 * 2) as u64 * (ref_hz as u64))) as u32;
}

; tap_resolution_ps(200 MHz), asserted below
pub const IDELAY_RESOLUTION_PS : u32 = 78;

pub fn clock_period_ps(hz : u32) u32 {
    return ((1_000_000_000_000 as u64) / (hz as u64)) as u32;
}

; Gigabit clocks run DDR (both edges); the 10/100 downshift drops to SDR --
; rising edge only -- or 25 MHz DDR would carry 200 Mbps, not 100.
pub fn mbps(clock_hz : u32, edges : u32) u32 {
    return (RGMII_DATA_BITS * edges * clock_hz) / 1_000_000;
}

pub fn taps_for_shift_ps(shift_ps : u32) u32 {
    return (shift_ps + IDELAY_RESOLUTION_PS - 1) / IDELAY_RESOLUTION_PS;
}

test gigabit_rate_is_the_product {
    assert mbps(RGMII_CLOCK_HZ, RGMII_EDGES) == RGMII_IDEAL_MBPS;
}

test period_is_8ns_in_ps {
    assert clock_period_ps(RGMII_CLOCK_HZ) == 8000;
    assert clock_period_ps(RGMII_CLOCK_HZ) / RGMII_EDGES == 4000;
}

test byte_every_two_edges {
    const bytes_per_s = (RGMII_IDEAL_MBPS * 1_000_000) / 8;
    assert bytes_per_s == 125_000_000;
}

; 100 Mbps = 25 MHz SDR, 10 Mbps = 2.5 MHz SDR (RGMII v2.0)
test downshift_rates {
    assert mbps(RGMII_100_HZ, 1) == 100;
    assert mbps(RGMII_10_HZ, 1) == 10;
    assert mbps(RGMII_100_HZ, 2) == 200;
    assert clock_period_ps(RGMII_100_HZ) == 40_000;
    assert clock_period_ps(RGMII_10_HZ) == 400_000;
}

test tap_resolution_is_78ps {
    assert tap_resolution_ps(IDELAY_REF_HZ) == 78;
    assert IDELAY_RESOLUTION_PS == tap_resolution_ps(IDELAY_REF_HZ);
}

test tap_range_covers_2ns {
    const range_ps = IDELAY_TAPS * IDELAY_RESOLUTION_PS;
    assert range_ps == 2418;
    assert taps_for_shift_ps(2000) == 26;
    assert taps_for_shift_ps(2000) <= IDELAY_TAPS;
    assert taps_for_shift_ps(4000) == 52;
    assert taps_for_shift_ps(4000) > IDELAY_TAPS;
}

test artix7_has_no_odelay {
    assert HAVE_ODELAY == false;
}

invariant rate_matches_clock {
    mbps(RGMII_CLOCK_HZ, RGMII_EDGES) == (RGMII_DATA_BITS * RGMII_EDGES * RGMII_CLOCK_HZ) / 1_000_000
}

Открыть спеку урока в плеере ↗

Все уроки