FM10K硬件指南——探索10420与10840
FM10K硬件指南——探索FM10420与FM10840
本文章适用于基于Intel FM10840的Silicom PE31625G24DIRA 和基于Intel FM10420的PE3100G2DQIR
这是一篇学习笔记,大部分内容都是AI生成整理。只为了解FM10K及更早先的架构设计。

关于Intel FM10K
2011年,intel收购了Microsystems 一家设计数据中心的 10GbE/40GbE Ethernet switch silicon。
重点优势包括高性能、低延迟和 workload balancing。在SDK中我们能看到FM2000-FM4000-FM6000的身影,当然这些只是Fulcrum 的前序作品。但是不得不承认,在FM6K之前这个芯片是一个正儿八经的Switch Chip,而不是在FM10K后变成了把 Ethernet switch fabric、PCIe host interfaces 和 Intel NIC datapath 融合在了一颗芯片里。

QDI / Asynchronous Architecture :Fulcrum 的异步交换芯片哲学
在研究 Fulcrum FM2000、FM4000、FM6000,乃至后来的 Intel FM10000 时,一个很难绕开的关键词就是:
QDI — Quasi-Delay-Insensitive Asynchronous Design
这不是一个普通的低功耗优化,也不仅仅是一种不同的 Clock Domain 设计方式。对于 Fulcrum 来说,异步电路几乎是整个公司最核心的技术资产之一。
从 Clock 开始:同步电路是如何工作的?
传统数字 ASIC 大部分采用 Synchronous Design。
最简单的流水线可以抽象成:
flowchart LR
A["Register A"] --> L1["Logic"]
L1 --> B["Register B"]
B --> L2["Logic"]
L2 --> C["Register C"]
CLK["Global Clock"] -.-> A
CLK -.-> B
CLK -.-> C
所有 Pipeline Stage 都由一个时钟系统统一推进:
Clock Edge
↓
Register 输出数据
↓
Combinational Logic 运算
↓
结果必须在下一个 Clock Edge 前稳定
↓
Next Register 捕获因此一个同步 Pipeline 的 Clock Period 必须满足一个非常重要的条件:
Tclock ≥ Tworst_case换句话说:
整个系统必须按照最慢的那个合法路径来设计时钟周期。
即使某一批数据实际只用了 400 ps 就完成计算,只要设计的 worst-case path 是 1 ns,这一级通常仍然要等到下一个 Clock Edge 才能继续。
同步 ASIC 因此需要处理 Clock Tree、Clock Skew、Setup/Hold Timing、Process/Voltage/Temperature variation 等大量时序问题。
Asynchronous Pipeline:不再等待 Clock
异步 Pipeline 的思路完全不同。
它没有要求每一级数据处理都等待同一个全局 Clock Edge,而是让相邻 Stage 之间通过 Handshake 协调。
可以把它简化成:
sequenceDiagram
participant A as Stage A
participant B as Stage B
participant C as Stage C
A->>B: Data + Request
B->>A: Acknowledge
B->>C: Data + Request
C->>B: Acknowledge逻辑上的意义是:
Stage A
│
│ 数据已经准备好
▼
Stage B
│
│ 我已经处理完成
▼
Stage C不再需要:
Wait...
Wait...
Clock Edge!而是:
Finished?
│
YES
↓
Continue immediatelyCaltech 对 QDI asynchronous circuits 的研究将这种设计建立在 handshake protocol、completion detection 和 delay-insensitive communication 等机制之上;QDI 电路只保留非常有限的 timing assumption,而不是依赖传统意义上的全局 Clock 来决定每一级何时完成。
QDI 中的关键思想:Completion Detection
这里才开始真正有意思。
同步电路隐含假设:
经过 1 ns
↓
计算应该完成了QDI 的思路则是:
不要猜什么时候完成。
让数据自己告诉你:
“我已经完成了。”因此典型的 QDI pipeline 会具有 Completion Detection:
flowchart LR
IN["Input"] --> A["Logic Stage A"]
A --> CA["Completion Detection"]
CA --> B["Logic Stage B"]
B --> CB["Completion Detection"]
CB --> C["Logic Stage C"]
C --> CC["Completion Detection"]
CC --> OUT["Output"]
只有当前 Stage 的输出被确认有效以后,Handshake 才允许后一级继续处理。
Fulcrum 在 Hot Chips 对自己的 Self-Timed Domino Logic Pipeline 描述中,正是把:
Dual-Rail Domino Logic
+
Completion Detection
+
Handshake Control组合在一起。Fulcrum 当时声称,这种实现相对于传统 static logic + flip-flop pipeline 可以显著降低 pipeline latency,同时避免大量无意义的 clock-driven switching。
Self-Timed Pipeline
把这些东西组合起来以后,一个 Fulcrum 风格的异步流水线可以简化为:
flowchart LR
A["Input"]
A --> S0["Dual-Rail<br/>Logic Stage 0"]
S0 --> C0["Completion<br/>Detection"]
C0 --> H0["Handshake"]
H0 --> S1["Dual-Rail<br/>Logic Stage 1"]
S1 --> C1["Completion<br/>Detection"]
C1 --> H1["Handshake"]
H1 --> S2["Dual-Rail<br/>Logic Stage 2"]
S2 --> C2["Completion<br/>Detection"]
C2 --> OUT["Output"]
它与同步流水线最本质的差异,可以总结成:
| Synchronous Pipeline | QDI Asynchronous Pipeline | |
|---|---|---|
| Pipeline 推进 | Clock Edge | Handshake |
| 完成判断 | 等待预定 Clock Period | Completion Detection |
| Timing | Worst-case timing | Data-dependent completion |
| 控制基础 | Global/Regional Clock | Local handshake |
| Pipeline Register | Flip-Flop/Register | Async pipeline / handshake state |
| Activity | Clock 持续运行 | 数据到来才驱动处理 |
| PVT 适应 | Timing closure 留 Margin | Completion mechanism 自然适应部分 delay variation |
但这里要避免一个常见误解:
Asynchronous 并不意味着“电路没有时间概念”。
相反,它对数据依赖、handshake、completion、fork timing 和物理实现仍然有非常严格的要求,只是不再使用传统 synchronous design 那种统一的 clock period 来协调所有计算。严格意义上的 QDI 也并非完全不做任何 timing assumption;例如经典 QDI 模型通常仍依赖有限的 isochronic-fork assumption。
为什么这套东西特别适合 Ethernet Switch ASIC?
这就涉及 Fulcrum 为什么愿意为这种非常复杂的设计方法投入如此多工程资源。
交换 ASIC 中大量高速数据结构恰好包括:
Crossbar
TCAM
SRAM
Scheduler
FIFO
Packet Pipeline而这些结构往往具有一个共同特点:
数据流非常规则,但吞吐量和延迟要求极高。
Fulcrum 在 Hot Chips 中明确指出,它认为 QDI 特别适合:
- Crossbar
- TCAM
- SRAM
并将高吞吐、低延迟、功耗效率以及对 manufacturing / operational variation 的鲁棒性列为主要优势。
这几乎正好对应 Ethernet Switch 的核心。
flowchart TB
RX["Ethernet RX"]
RX --> XBAR["Crossbar"]
XBAR --> MEM["Shared SRAM"]
MEM --> FP["Frame Processing"]
FP --> TCAM["TCAM / Classification"]
FP --> SRAM["Lookup SRAM"]
TCAM --> SCHED["Scheduler"]
SRAM --> SCHED
SCHED --> XBAR2["Egress Crossbar"]
XBAR2 --> TX["Ethernet TX"]
换句话说:
Fulcrum 并不是为了“异步而异步”。它找到的是一种非常适合 高速交换数据通路 的异步计算模型。
RapidArray™ Shared-Memory Architecture:共享内存交换架构
如果说 QDI 是 Fulcrum 在 circuit level 上最具代表性的技术,那么:
RapidArray™
就是这套设计哲学在 switch architecture level 上最直接的体现。
Intel 后来的 FM5000/FM6000 Datasheet 对 RapidArray 给出了一个非常明确的定义:
Single-output-queued shared-memory architecture
而且明确指出,这套架构从 FM2000、FM4000 一直延续到 FM5000/FM6000。
从架构上看,RapidArray 并不是简单的:
Port
↓
Crossbar
↓
Port而是一套完整的:
Ingress
↓
Crossbar
↓
Shared Packet Memory
↓
Scheduler
↓
Crossbar
↓
Egress系统。
这也是为什么只看 Fulcrum 芯片的 Ethernet Port 数量,很容易低估它真正有意思的地方。
从 Packet 的角度看 RapidArray
在 FM5000/FM6000 中,一个 Packet 进入 ASIC 后,大致会经历:
flowchart LR
RX["Ethernet RX"]
RX --> EPL["EPL<br/>PCS / MAC"]
EPL --> IX["Ingress Crossbar"]
IX --> MEM["Shared Packet Memory"]
IX -. "First 112 Bytes" .-> FPP["Frame Processing Pipeline"]
FPP --> DEC["Forwarding Decision<br/>DMASK / Modify Info"]
DEC --> SCHED["Scheduler"]
MEM --> EX["Egress Crossbar"]
SCHED --> EX
EX --> MODIFY["Egress Modifier"]
MODIFY --> TX["Ethernet TX"]
这个图里其实存在两条相互配合、但非常不同的数据路径:
Packet Payload
│
└──→ Shared Memory
Packet Header
│
└──→ Frame Processing Pipeline也就是说:
大块 Packet Data 和 Forwarding Decision 并不需要沿着同一条流水线传播。
FM6000 的 Ingress Crossbar 将 Packet 按 160-byte segment 写入 Shared Memory,而第一个 segment 的前 112 bytes 会同时被送往 Frame Handler,用于 switching、routing 和 classification。
这种分离非常重要。
因为交换芯片真正需要高速分析的通常只是:
Ethernet Header
VLAN
MPLS
IPv4 / IPv6
TCP / UDP
Tunnel Header
Metadata没有必要让一个 1500-byte Packet 的所有内容全部穿过复杂的 TCAM / Lookup Pipeline。
因此:
Payload → Memory
Header → Intelligence这可以看作 RapidArray 与 FlexPipe 之间最基础的分工。
Ingress Crossbar
当 Packet 从 Ethernet Port 进入时,首先经过:
Ingress Crossbar
FM6000 的 Ingress Crossbar 会把连续的 Ethernet stream 转换成 160-byte segments,然后写入中央 Packet Memory。
FM5000/FM6000 的 Ingress / Egress Crossbar 最多支持 76 个 full-duplex logical channels;每个 channel 可以提供 10GbE throughput,40GbE 则由四个 channel 组合,整个 switch fabric 的 aggregate bandwidth 为 720GbE。
可以简化理解为:
flowchart LR
P0["Port 0"] --> X["Ingress Crossbar"]
P1["Port 1"] --> X
P2["Port 2"] --> X
P3["Port 3"] --> X
PN["..."] --> X
X --> M0["Memory Segment"]
X --> M1["Memory Segment"]
X --> M2["Memory Segment"]
X --> M3["Memory Segment"]
Crossbar 的作用并不是决定 Packet 最终应该去哪。
它解决的是另一个问题:
如何让大量高速 Port 同时访问中央 Memory。
至于:
Packet 最终应该从哪个 Port 发出去?
这是 Frame Processing Pipeline 与 Scheduler 的工作。
Shared Memory:所有 Port 共用一个 Buffer Pool
RapidArray 的核心是:
Shared Memory
FM6000 的 Main Packet Memory 为 7.5 MB,如果把其他功能模块中的 Packet/Header Memory 一并计算,总量大约为 9.5 MB。
但真正重要的并不是数字,而是:
这些 Buffer 并不是简单静态绑定给某个 Ethernet Port。
Intel 在 Datasheet 中直接描述 FM5000/FM6000:
fundamentally is a shared memory switch
中央 Frame Memory 可以被所有 Port 使用。
概念上可以理解成:
Static Per-Port Buffer
Port 1 ██████████
Port 2 ██
Port 3
Port 4 █如果 Port 1 已经塞满:
Port 1 → DROP即使:
Port 3 Buffer = Empty
Port 4 Buffer = Empty这些空间也未必能够拿来给 Port 1 使用。
RapidArray 的思想则更接近:
Shared Buffer Pool
┌─────────────────────────┐
Port 1 ─┤████████████ │
Port 2 ─┤██ │
Port 3 ─┤ │
Port 4 ─┤█ │
└─────────────────────────┘Buffer 不再首先属于某一个物理 Port,而是一项共享资源。
这意味着交换芯片能够根据实际 Traffic Pattern 更灵活地使用有限的 on-chip SRAM。
Packet 并不是作为一个连续大块存储
这里还有一个非常值得写的设计。
FM6000 将 Packet 切分成:
160-byte segments
例如一个约 1500-byte Ethernet frame,可以抽象成:
Frame
│
├── Segment 0
├── Segment 1
├── Segment 2
├── Segment 3
├── Segment 4
├── Segment 5
├── Segment 6
├── Segment 7
├── Segment 8
└── Segment 9Scheduler 维护:
Free Segment List
Receive Queues
Transmit Queues
Segment ChainsIncoming packet 到达时,Scheduler 从 Free Segment Pool 分配 storage;Packet 完成 classification 后,再将相关 segment 信息放入对应的 transmission queue。
因此更准确的模型不是:
TX Queue
↓
[Whole Packet]
[Whole Packet]
[Whole Packet]而是:
flowchart LR
Q["Logical TX Queue"]
Q --> P0["Packet A<br/>Segment List"]
Q --> P1["Packet B<br/>Segment List"]
Q --> P2["Packet C<br/>Segment List"]
P0 --> M["Shared Packet Memory"]
P1 --> M
P2 --> M
真正的大块 Packet Payload:
只存在中央 Shared Memory 中。
Queue 更重要的是管理:
Which frame?
Which segments?
Which destination?
When can it transmit?Single Output Queued 到底是什么意思?
Intel 对 RapidArray 的正式术语是:
Single Output Queued Shared Memory Architecture。
从 Forwarding Model 看,它可以理解为:
Ingress Port
│
▼
Shared Memory
│
▼
Logical Egress Queue
│
▼
Scheduler
│
▼
Egress Port也就是说,Packet 真正需要等待的是:
它所对应的输出调度资源。
而不是简单地被固定困在 ingress port 自己的 FIFO 中。
这对交换芯片非常重要,因为它避免了最简单 input FIFO 架构中容易遇到的:
Head-of-Line Blocking
问题。
例如:
Ingress Queue:
Packet A → Port 1 [Blocked]
Packet B → Port 2 [Free]
Packet C → Port 3 [Free]一个简单 FIFO 可能因为:
Packet A cannot move导致:
Packet B
Packet C也一起被挡在后面。
而 Shared Memory + Output Scheduling 的思路,是把:
Where the frame is stored与:
When the frame is transmitted分离开。
Scheduler 才是 RapidArray 真正的大脑
Shared Memory 自己不会决定:
谁先发送?这件事情由:
Scheduler
负责。
FM6000 Scheduler 管理:
- Free segment
- Receive queue
- Transmit queue
- Packet scheduling
- Segment list
- Traffic class
- Egress arbitration
并最终告诉 Egress Crossbar:
下一次应该从 Shared Memory 中读取哪些 Segment。
Intel Datasheet 描述的流程大致是:
flowchart TB
FREE["Free Segment Pool"]
FREE --> IX["Ingress Crossbar"]
IX --> MEM["Shared Memory"]
HDR["Frame Header"] --> FPP["Frame Processing"]
FPP -->|"Destination / Priority"| S["Scheduler"]
S --> TXQ["TX Queues"]
TXQ --> PICK["Scheduling Decision"]
PICK -->|"Segment List"| EX["Egress Crossbar"]
MEM --> EX
EX --> TX["Transmit"]
Scheduler 还需要同时处理数以千计的 queue/event。
Fulcrum 在 Hot Chips 23 对 Alta 的设计挑战中直接指出:
720G Switch / Scheduler
67 ns scheduling period
over 1000 queues
up to 150 MHz
per-queue event rate并把它称为一个:
very challenging asynchronous design problem。
这就把上一章讨论的 QDI 真正连接到了 RapidArray。
FlexPipe™ Packet Processing Pipeline:从固定功能交换到 Match-Action 数据平面
如果说 RapidArray™ 解决的是:
How does the packet move through the switch?
那么 FlexPipe™ 解决的就是:
What should the switch do with the packet?
对于今天熟悉 P4、PISA、programmable data plane 的工程师来说,Match → Action → Metadata → Next Stage 已经是一种相当自然的思维方式。
但在 FM6000 所处的 2010~2011 年,这种思想还远没有今天这么普遍。
Fulcrum 在设计 Alta / FM6000 时面对的问题,并不是简单增加几个 VLAN、ACL 或 Routing Feature,而是:
随着协议和功能不断增加,继续为每一种网络功能设计独立的硬编码逻辑模块,复杂度正在迅速失控。
Hot Chips 23 中 Fulcrum 给 Alta 列出的需求已经包括:
L2 Switching
IPv4 / IPv6 Routing
IP Multicast
5-Tuple ACL
MPLS
TRILL
Q-in-Q
PBB / PBT
DCB
PFC
Congestion Notification
sFlow
Advanced Hashing
Pseudo-Random Load Balancing
Virtualization
Tunneling而 Alta 最终甚至在 specification closure 之后,又通过 Pipeline Configurability 支持了 FCoE、Native Fibre Channel、IP-in-IP、IPv4/IPv6 Translation、GRE、NAT、VEPA、VN-Tag、VPWS/VPLS、LISP 和早期 OpenFlow 等功能。
这就是 FlexPipe 出现的背景。
传统思路:为每一种功能造一个 Engine
一个典型的传统交换 ASIC,可以抽象成:
flowchart LR
RX["Ethernet RX"]
RX --> PARSER["Parser"]
PARSER --> VLAN["VLAN Engine"]
VLAN --> L2["L2 Forwarding"]
L2 --> L3["L3 Routing"]
L3 --> ACL["ACL Engine"]
ACL --> TUN["Tunnel Engine"]
TUN --> QOS["QoS"]
QOS --> MOD["Header Rewrite"]
MOD --> TX["Ethernet TX"]
这种设计的优势非常明显:
- 每个模块针对特定功能优化;
- 行为容易预测;
- 功耗和面积相对容易控制;
- 软件 SDK 只需要配置预定义 Feature。
但是它也存在一个问题:
New Protocol
↓
Existing Engine cannot understand it
↓
Need New Logic
↓
New Silicon Revision如果突然出现一种新的 encapsulation:
Ethernet
↓
NewHeader
↓
IPv6
↓
UDP而 Parser、ACL、Tunnel Engine 在 Tape-out 时并没有考虑 NewHeader,那么 ASIC 的灵活性就会受到明显限制。
Fulcrum 决定从另外一个角度思考这个问题。
不要实现 Protocol,实现 Computation
这是 FlexPipe 最值得写的一句话。
Fulcrum 在 Hot Chips 中总结交换 ASIC 的 Packet Processing,发现大量不同网络功能最终都可以归纳为几个非常基本的计算:
Pattern Matching
Mapping Tables
Simple Guarded Assignments
Muxing于是 Alta 的设计原则变成了:
Implement the abstract computations, not hard-coded details.
也就是:
不要直接做:
"IPv4 Routing Engine"
而是提供:
Match
Lookup
Map
Action
Modify然后再通过配置这些基础硬件资源,去表达:
IPv4 Routing
IPv6 Routing
ACL
Tunnel
VLAN
MPLS
Multicast
...Fulcrum 由此把交换处理过程进一步分解为非常经典的一组 primitive:
flowchart LR
H["Header Fields / Metadata"]
H --> T["TCAM<br/>Pattern Match"]
T --> R["Action SRAM<br/>Rule → Command"]
R --> A["Action Logic"]
H --> M["Operand / Field Selection"]
M --> A
A --> X["MUX / Crossbar"]
X --> O["Updated Header Fields<br/>+ Metadata"]
TCAM 找:
Which rule matches?Action RAM 决定:
What action belongs to this rule?Action Logic 和 MUX 则完成:
How should the metadata/header be transformed?Fulcrum 把这一结构称为通用的 TCAM/RAM/MUX Stage。
TCAM → Action SRAM:早期 Match-Action
假设我们要实现:
如果:
Packet 是 IPv4
&&
Route Valid
&&
不是 Multicast
那么:
根据 Route Result 修改 DMAC传统 RTL 可能直接写成:
IF IPv4 && RouteValid && !Multicast
DMAC = NextHopMAC而 FlexPipe 可以把它转成:
flowchart LR
KEY["IPv4<br/>RouteValid<br/>Multicast<br/>Metadata"]
KEY --> TCAM["TCAM"]
TCAM -->|"Rule #37"| RAM["Action SRAM"]
RAM -->|"REWRITE_DMAC"| ACTION["Action Logic"]
ACTION --> OUT["Updated Metadata"]
于是硬件不需要知道:
Rule #37为什么代表 IPv4 routing。
它只需要知道:
Key matches entry 37
↓
Read Action 37
↓
Perform transformationFulcrum 的 Action RAM 就是将 winning TCAM rule number 映射成一组 transformation controls。
从今天的视角看,这个结构非常熟悉:
MATCH
↓
ACTION
↓
METADATAPipelined Loop Unrolling
如果只有一次:
Match → Action其实还不足以完成复杂 Ethernet Forwarding。
一次 Packet Processing 通常存在依赖关系:
先解析 EtherType
然后才能知道:
这是 IPv4
然后才能查 Route
Route Lookup 之后:
才能得到 NextHop
NextHop 之后:
才能获得新的 DMAC
之后才能:
执行新的 L2 Lookup
最后才能:
确定 Egress Destination于是 Fulcrum 做了一件非常重要的事情:
把多个 Match / Lookup / Action Stage 串联起来。
flowchart LR
META0["Metadata v0"]
META0 --> M0["Match"]
M0 --> A0["Action"]
A0 --> META1["Metadata v1"]
META1 --> M1["Match"]
M1 --> A1["Action"]
A1 --> META2["Metadata v2"]
META2 --> M2["Match"]
M2 --> A2["Action"]
A2 --> META3["Metadata v3"]
META3 --> DOT["..."]
DOT --> OUT["Final Metadata"]
关键在于:
前一级产生的结果,可以继续成为后一级的输入。
所以:
Stage 0
判断是什么 Packet
↓
Stage 1
根据类型做 Classification
↓
Stage 2
根据 Classification 做 Route Lookup
↓
Stage 3
根据 Route Result 找 NextHop
↓
Stage 4
根据 NextHop 决定新的 L2 信息Fulcrum 将这种方式称为:
Pipelined Loop Unrolling
并明确指出,每一级的 TCAM Key、TCAM/RAM 容量以及 Action Function 都可以不同。重复这些 Stage 后,就能形成 fully-pipelined iterative header transformations。
FlexPipe 不是一排完全相同的 Stage
这一点非常重要。
FlexPipe 不是后来 RMT/PISA 那种高度规则化的 homogeneous Match-Action Pipeline。
它是一条:
Heterogeneous Pipeline
Fulcrum 根据不同任务,为每一段配置不同类型的资源。
主要可以分成三类。
CAM/RAM Programmable Stages
例如:
PARSER
FFU
L3AR
L2AR重点资源是:
TCAM
+
Action RAM非常适合:
Classification
ACL
Pattern Matching
Metadata TransformationTable Lookup Action Stages
例如:
NEXTHOP
L2F
MCAST更强调:
Large SRAM Table适合:
Index
↓
Lookup
↓
Result Mapping比如:
NextHop Index
↓
NextHop Table
↓
DMAC / VLAN / Tunnel InformationFixed-Function Action Stages
例如:
ALU
POLICER
COUNTER
HASH这些地方则没有必要为了“可编程”而强行使用 TCAM。
专用硬件实现:
Arithmetic
Checksum
Hash
Range Compare
Policing
Statistics面积和效率会更好。
因此 FlexPipe 实际上更接近:
flowchart LR
TC0["TCAM-heavy<br/>Stage"]
TC0 --> RAM0["RAM-heavy<br/>Stage"]
RAM0 --> ALU["ALU / Hash<br/>Stage"]
ALU --> TC1["TCAM-heavy<br/>Stage"]
TC1 --> LOOK["Lookup-heavy<br/>Stage"]
LOOK --> MOD["Rewrite<br/>Stage"]
而不是:
Generic Stage
Generic Stage
Generic Stage
Generic Stage这也是为什么称它为:
heterogeneous programmable pipeline
会比单纯说“programmable switch”更加准确。
Parser 本身也是 Pipeline 的一部分
FlexPipe 的灵活性甚至从 Parser 就已经开始了。
Fulcrum 的 Configurable Parser 会逐步读取 Packet Header,并维护:
STATE
FLAGS
FIELDS
CHECKSUM例如解析到:
EtherType = IPv4它可以生成:
FLAGS.IsIPv4 = 1
FIELDS.L2TYPE = 0x0800
STATE.Header = IPv4
这些 Metadata 随后继续向 FFU、NextHop 等后续 Stage 传播。Alta 的 Parser 被实现成 fully-pipelined、loop-unrolled parsing state machine,Hot Chips 资料给出的固定最大 parsing depth 为 128 bytes。
可以简单画成:
flowchart LR
RAW["Raw Packet"]
RAW --> P["Parser"]
P --> F["Extracted Fields"]
P --> FLAGS["Flags"]
P --> STATE["Parser State"]
F --> FFU["FFU"]
FLAGS --> FFU
STATE --> FFU

也就是说:
FlexPipe 操作的核心并不是整个 Packet Payload,而是一条不断被丰富和修改的 Header + Metadata Bus。
FFU:FlexPipe 的 Match-Action 核心
FlexPipe 中最具代表性的模块之一就是:
FFU — Filtering and Forwarding Unit
它并不是简单的一块“大 ACL TCAM”。
FFU 内部包含多组:
CAM
↓
Action RAM
↓
Action Cascade并允许前一组 Slice 的结果成为后续 Slice 的 Key。

所以它可以形成:
flowchart LR
KEY0["Header + Metadata"]
KEY0 --> CAM0["CAM Slice"]
CAM0 --> RAM0["Action RAM"]
RAM0 --> A0["Action Cascade"]
A0 --> KEY1["Derived Metadata"]
KEY1 --> CAM1["CAM Slice"]
CAM1 --> RAM1["Action RAM"]
RAM1 --> A1["Action Cascade"]
A1 --> OUT["Accumulated Actions"]
Fulcrum 特别指出,第一组 CAM Slice 的输出可以进入下一组,实现:
Second-order iterative matching。
这意味着:
Match
↓
Derive Information
↓
Match Again
↓
Derive More Information而不是:
ACL Lookup
↓
Done为什么这种设计特别有价值?
最能说明问题的是 Alta Tape-out 后发生的事情。
Fulcrum 在设计阶段并没有把所有未来 Feature 都列进规格。
但最终他们发现,由于 Pipeline 本身具有足够的可配置性,Alta 可以支持很多在 specification closure 后才确认的功能,例如:
FCoE
Native Fibre Channel
IP-in-IP
IPv4 ↔ IPv6 Translation
GRE
NAT
VEPA / VEPA+
VN-Tag
VPWS / VPLS
LISP
OpenFlow 0.9 / 1.0 / 1.1Fulcrum 在 Hot Chips 中直接把这些称为:
Bonus Features
并明确将其归功于 Pipeline Configurability。
这可能就是 FlexPipe 最能体现价值的地方:
Traditional ASIC:
New Feature
↓
Need New Silicon
FlexPipe:
New Feature
↓
Can existing Match / Lookup / Action
resources express it?
│
├── Yes → Microcode / Table Configuration
│
└── No → Need New SiliconFlexPipe 当然不能解决所有问题。
但它显著扩大了:
Tape-out 之后还能通过软件重新解释硬件的范围。
Broadcom vs Fulcrum
可以把两种思路概括成:
| Broadcom Trident | Fulcrum FlexPipe | |
|---|---|---|
| 设计中心 | 丰富的专用 Forwarding Engines | 可配置的 Processing Pipeline |
| Parser | Frame Parser | Configurable Parser |
| VLAN | Dedicated VLAN Engine | Match/Lookup/Action 组合 |
| L2 | Dedicated L2 Forwarding | L2 Lookup + GloRT + L2F |
| L3 | Dedicated L3 Routing | FFU + NextHop + L3AR |
| ACL | Multistage ContentAware Engine | FFU TCAM/Action RAM |
| Tunnel | Dedicated Tunneling Engine | Pipeline + NextHop + Modify |
| Action Model | Engine-oriented | Distributed Match/Map/Action |
| Pipeline | Function-oriented | Heterogeneous computational stages |
| 软件配置 | Configure predefined features | Configure tables + microcode-like behavior |
| 灵活性重点 | Feature richness | Expressing features through generic primitives |
两条路线最终都能:
Switch
Route
ACL
Tunnel
QoS但是思考问题的方法不同。
Broadcom 更接近:
Build powerful forwarding engines
↓
Expose them through SDK而 Fulcrum 更接近:
Build reusable computational primitives
↓
Compose forwarding behavior from them这正是 FlexPipe 最独特的地方。
FlexPipe 与 RapidArray
现在就可以把前两节真正连接起来。
flowchart LR
RX["Ethernet RX"]
RX --> RA["RapidArray<br/>Ingress"]
RA --> MEM["Shared Memory"]
RA --> FLEX["FlexPipe"]
FLEX -->|"Destination"| SCH["Scheduler"]
FLEX -->|"QoS"| SCH
FLEX -->|"Modify Commands"| MOD["MODIFY"]
MEM --> SCH
SCH --> MOD
MOD --> RA2["RapidArray<br/>Egress"]
RA2 --> TX["Ethernet TX"]
两套架构各自负责:
RapidArray
↓
Where is the packet stored?
When can the packet move?
FlexPipe
↓
What is the packet?
Where should it go?
What should be done to it?可以进一步浓缩成:
RapidArray = Movement
FlexPipe = Intelligence而它们共同构成了 Fulcrum Switch Architecture 最核心的两部分。
GloRT:逻辑目的地与交换 Fabric 寻址
在传统 Ethernet Switch 中,我们习惯把转发理解成:
DMAC + VLAN
↓
MAC Table
↓
Physical Port例如:
00:11:22:33:44:55
↓
MAC Table Lookup
↓
Port 17这套模型对于一颗独立交换芯片来说非常自然。
但 Fulcrum 从 FM5000/FM6000 开始面对的已经不只是:
一个 Packet 应该从哪个物理 Port 发出去?
而是更加复杂的问题:
如果一个逻辑交换机由多颗 ASIC 组成怎么办?
如果 Destination 是一个 LAG,而不是一个 Port 呢?
如果 Destination 是 Multicast Group、CPU、Mirror Destination 呢?
到了 FM10000,如果 Destination 甚至不是 Ethernet Port,而是一个 PCIe Host、VF 或 Tunnel Engine 呢?
Fulcrum 为此引入了一个非常重要的抽象:
GloRT — Global Resource Tag
到了 FM10000,Intel 又在它外面发展出了:
FTAG — Fabric Tag
这两个机制共同构成了 FM6000 → FM10000 架构中一个非常独特的 Logical Fabric Addressing System。
GloRT:不要把 Destination 直接写成 Physical Port
FM5000/FM6000 Datasheet 对 GloRT 的定义非常明确:
GloRT 是一个 16-bit number,可以表示特定 Port、Link Aggregation Group、Multicast Group、Management Frame,或者 Single/Multi-stage Fabric 中的其他 Packet Destination。
所以传统思路:
Destination = Port 17在 Fulcrum 中可以变成:
Destination = GloRT 0x4200至于:
0x4200最后到底代表:
Port 17还是:
LAG 5甚至:
另一颗 FM6000 上的一组 Port由后面的 GloRT Resolution 决定。
GloRT 本质上是一个 Logical Port
FM6000 Datasheet 对这个思想有一句非常关键的描述:
FM5000/FM6000 在概念上是一颗运行在 virtualized physical layer 上的 switch-router。
在这层抽象中,一个“Port”可以表示:
- Physical Ethernet Port
- LAG
- Remote CPU
- Attached CPU
- Internal Loopback Entity
- Multicast Group
- Load-Balancing Group
- 甚至分布在多颗 FM6000 ASIC 上的资源。
因此可以把它理解成:
flowchart LR
P["Packet"]
P --> G["Destination GloRT"]
G --> R["GloRT Resolution"]
R --> PHY["Physical Port"]
R --> LAG["LAG"]
R --> MC["Multicast Group"]
R --> CPU["CPU"]
R --> REMOTE["Remote ASIC"]
这其实是一个非常漂亮的抽象:
Logical Destination
↓
Physical Realization被彻底分离了。
SGLORT 与 DGLORT
一个 Packet 在 Fulcrum Fabric 中通常会存在两个非常重要的身份:
SGLORT
Source Global Resource Tag
DGLORT
Destination Global Resource Tag它们的意义可以简单理解为:
SGLORT = Where did this frame come from?
DGLORT = Where should this frame go?例如:
flowchart LR
SRC["Physical Port 3"]
SRC -->|"SGLORT = 0x1200"| P["Packet"]
P --> FWD["FlexPipe"]
FWD -->|"DGLORT = 0x4200"| DST["Logical Destination"]
在 FM5000/FM6000 中,一个没有携带 Inter-Switch Fabric Tag 的 Frame 从物理端口进入时,会被赋予该 Port 对应的 Per-Port Source GloRT。如果随后发生 Source MAC Learning,这个 Source GloRT 甚至会和 Source MAC 一起写入 MAC Table。
所以 MAC Table 中的 forwarding result 并不一定是:
MAC
↓
Port Number而可以更准确地理解成:
MAC
↓
GloRT
↓
Physical Destination Resolution为什么不能直接在 MAC Table 里保存 Port?
因为如果保存:
MAC → Port 17这个 entry 天生就是:
Local ASIC Specific
换一颗 ASIC:
Port 17可能完全代表另外一个物理接口。
但如果保存:
MAC → GloRT 0x4200那么:
0x4200可以在整个 Multi-chip Fabric 中保持同一个逻辑含义。
不同芯片只需要知道:
我应该如何把
0x4200映射到我自己的本地出口?
于是就可以形成:
flowchart LR
A["ASIC A"]
A -->|"DGLORT 0x4200"| B["Fabric"]
B --> C["ASIC B"]
C -->|"Resolve 0x4200"| P["Physical Port 7"]
对于 ASIC A:
0x4200
↓
Send toward ASIC B对于 ASIC B:
0x4200
↓
Physical Port 7同一个 Logical Destination,不同 ASIC 做不同的 local resolution。
这正是 GloRT 真正有价值的地方。
从 GloRT 到 Physical Port:不是一次简单查表
GloRT 也不是:
GloRT → Port这么简单。
FM6000 的 GloRT Lookup 本身就是 FlexPipe 中一个相当完整的 Stage。

处理过程大约为:
flowchart LR
D["DGLORT<br/>16 bit"]
D --> CAM["GLORT_CAM<br/>1K TCAM"]
CAM --> TABLE["GLORT_TABLE"]
TABLE --> IDX["DMASK_IDX"]
IDX --> MASK["Destination Mask Table<br/>16K Entries"]
MASK --> DMASK["76-bit DMASK"]
DMASK --> FILTER["VLAN / STP / ACL / LAG<br/>Filtering"]
FILTER --> FINAL["Final Physical<br/>Destination Ports"]
FM6000 的 GloRT Stage 首先使用一个 1K-entry TCAM/RAM 匹配 DGLORT,然后产生 Destination Mask Table 的索引;随后一个 16K-entry Destination Mask Table 将这个索引转换为 Physical Destination Mask。
所以:
DGLORT
↓
Logical Destination Resolution
↓
DMASK_IDX
↓
Physical Destination BitmapDMASK:GloRT 最终变成真正的物理出口
FM6000 的 Physical Forwarding 最终使用一个:
76-bit Destination Mask — DMASK
其中:
DMASK[n] = 1表示:
Forward one copy to physical destination n例如:
DMASK
00000000 00000000 00000000 00100100
↑ ↑
Port 5 Port 2表示 Packet 需要复制到两个 Destination。
但 GloRT Lookup 只是产生最初的 forwarding distribution。
之后 DMASK 还要经历:

FM6000 Datasheet 明确列出了这一过程:Initial GloRT mapping 之后,还会依次受到 VLAN Membership、STP、LAG、Security Policy、CPU Trap、Mirroring 以及 Congestion Management 等条件影响。
这说明一个很重要的问题:
GloRT 表示的是逻辑上的“我要去哪里”,DMASK 才是当前 ASIC 最终实际使用的 Physical Egress Set。
因此可以写成:
GloRT
=
Logical Destination
DMASK
=
Physical RealizationGloRT 甚至可以直接表示 LAG
这就是这套架构开始体现威力的地方。
假设:
GloRT 0x4200 = LAG A而 LAG A 包含:
Port 1
Port 3
Port 7
Port 11逻辑上 FlexPipe 只需要说:
DGLORT = 0x4200不需要关心最终到底走:
Port 1还是:
Port 7随后 GloRT Stage 可以结合:
L2_HASH执行:
LAG Pruning
+
LAG Filtering最终从这个逻辑 Group 中选择一个 Physical Member。FM6000 的 GloRT Lookup 甚至允许不同 GloRT Entry 选择不同 Hash Rotation 来完成这一过程。

因此:
flowchart LR
FLOW["Packet"]
FLOW --> G["DGLORT<br/>LAG A"]
G --> HASH["L2 Hash"]
HASH --> RESOLVE["GloRT Resolution"]
RESOLVE --> P1["Port 1"]
RESOLVE -.-> P3["Port 3"]
RESOLVE -.-> P7["Port 7"]
RESOLVE -.-> P11["Port 11"]
这就把:
Forwarding Decision与:
Load-Balancing Decision分离了。
FlexPipe 决定:
去 LAG A。
GloRT/LAG Logic 决定:
这一个 Flow 实际走 LAG A 的哪条 Link。
Multi-Chip Fabric:GloRT 真正的目标
到这里,就可以理解为什么 Fulcrum 不满足于传统:
MAC → Physical Port了。
假设我们有四颗 FM6000:
flowchart TB
S0["FM6000 #0"]
S1["FM6000 #1"]
S2["FM6000 #2"]
S3["FM6000 #3"]
S0 <--> S1
S0 <--> S2
S1 <--> S3
S2 <--> S3
站在软件层面,可以希望它们不是:
Four separate switches而是:
One Logical Switch于是:
Port
LAG
Multicast Group
CPU都不应该被限制在某一颗 ASIC 的 local numbering space。
Fulcrum 因此构造出:
Global Logical Address Space
│
GloRT
│
┌───────────────┼───────────────┐
▼ ▼ ▼
FM6000 #0 FM6000 #1 FM6000 #2
│ │ │
Local Port Local Port Local PortFM6000 Datasheet甚至明确把多个 FM5000/FM6000 组成的系统称作一个:
multi-chip domain
而这些 ASIC 通过 Fabric Tag 携带逻辑 Port 信息,从而构成统一的虚拟 Physical Layer。
问题来了:GloRT 怎样跨 ASIC?
GloRT 是 ASIC 内部的 Metadata。
但 Ethernet Link 本身只传:
DMAC
SMAC
EtherType
Payload
...如果 Packet 从:
ASIC A进入:
ASIC BASIC B 怎么知道:
Original SGLORT
Destination DGLORT
Internal Priority
Fabric State这些信息?
这就是:
Fabric Tag
存在的意义。
FM6000 时代:F56 / F64 / F96
事实上,FTAG 的思想并不是 FM10000 才突然出现。
FM5000/FM6000 已经支持多种 Intel/Fulcrum 私有的 Inter-Switch Tag:
F56
F64
F96用于 Multi-chip Switching。Intel 官方 Datasheet 明确说明,多颗 Switch 可以通过普通 Ethernet Port 互联,并扩展 Ethernet Frame Format 来携带额外 Fabric Information。
因此逻辑上已经是:
Ethernet Frame
+
Fabric Metadata
↓
Inter-Switch LinkGloRT 负责:
Logical IdentityFabric Tag 负责:
Transport Logical IdentityFM10000:FTAG 成为体系核心
到了 FM10000,这套概念被进一步扩展成非常明确的:
Fabric Tag — FTAG
Intel FM10000 Datasheet 对它的定义非常值得注意:
FTAG 可以在:
Switch ↔ Switch
Switch ↔ PCIe Host Interface
Switch ↔ Tunneling Engine之间携带内部信息。
Intel甚至明确表示,它对于多个 Switch 表现成:
one switch
是必要的。
这也是 FM10000 与普通 NIC 开始出现本质区别的地方。
FTAG 里装了什么?
FM10000 的 FTAG 包括:
USER 8 bit *
FTYPE 2 bit
SWPRI 4 bit
DGLORT 16 bit
SGLORT 16 bit
VPRI 4 bit
VID 12 bit其中 USER 字段用于 PCIe / Tunnel Engine 形式的 FTAG,在 Ethernet Switch-to-Switch FTAG 中不可用。

从功能上看可以整理成:
| Field | 作用 |
|---|---|
| SGLORT | Packet 的逻辑 Source |
| DGLORT | Packet 的逻辑 Destination |
| SWPRI | Fabric 内部 Switching Priority |
| VID | Fabric 中关联的 VLAN ID |
| VPRI | VLAN Priority |
| FTYPE | Normal / Special Frame |
| USER | PCIe/Tunnel 使用的额外 Metadata |
Intel FM10000 Datasheet明确规定了这些字段,而 DPDK 也把 FTAG 描述为携带 Packet 来源、目的地以及 VLAN 等 Fabric Information 的特殊 Tag。
所以 FTAG 很像:
┌──────────────────────────────────────────┐
│ Fabric Metadata │
├───────────┬───────────┬──────────────────┤
│ SGLORT │ DGLORT │ Priority / VLAN │
├───────────┴───────────┴──────────────────┤
│ Ethernet Frame │
└──────────────────────────────────────────┘一个特别漂亮的设计:Ethernet FTAG 可以复用 Preamble
普通 Ethernet Frame 开始时:
Preamble
↓
SFD
↓
DMAC
SMAC
...而 FM10000 在 Switch-to-Switch Ethernet Link 上,可以复用 Ethernet Preamble 的空间来携带 FTAG。
Intel 给出的设计目的是:
避免因为加入 Fabric Metadata 而额外消耗 Link Bandwidth。
而在:
PCIe Host Interface或:
Tunnel Engine方向,FTAG 则直接加在 Frame 前面。
所以:
flowchart TB
subgraph ETH["Switch ↔ Switch"]
E1["Ethernet Frame"]
E2["Preamble Space<br/>carries FTAG"]
E2 --> E1
end
subgraph PCIE["PCIe / Tunnel"]
P1["FTAG"]
P2["Ethernet Frame"]
P1 --> P2
end
这是 FM10000 Datasheet 对 Frame Tagging 的直接描述。
而且 Ethernet Port 上的 FTAG 是:
per-port enabled
并且 Intel 要求这种模式用于受信任的 Switch-to-Switch 链路,而不是普通外部 Ethernet Endpoint。
FTAG 和 VLAN Tag 不是一回事
看到:
VID
VPRI很容易误以为 FTAG 是另外一种 VLAN Tag。
不是。
VLAN Tag 描述:
Tenant / Broadcast Domain / Priority而 FTAG 描述的是:
Fabric Forwarding Context它实际上把:
Original Logical Source
Logical Destination
Switch Priority
VLAN Context
Frame Type一起带过去。
因此更接近:
Internal Fabric Header而不是:
802.1Q VLAN HeaderFTAG 最重要的是保留 DGLORT
假设 Switch A 已经做完:
DMAC Lookup
↓
DGLORT = 0x4200如果 Packet 去到下一颗 Switch 后重新执行:
DMAC + VLAN Lookup不仅重复工作,而且可能因为两颗芯片的 Local State 不同而得到不同结果。
有 FTAG 后:
flowchart LR
A["Switch A"]
A --> LOOKUP["L2 / L3 Lookup"]
LOOKUP --> G["DGLORT = 0x4200"]
G --> FT["FTAG"]
FT --> LINK["Fabric Link"]
LINK --> B["Switch B"]
B --> RESOLVE["Resolve DGLORT"]
RESOLVE --> PORT["Local Physical Port"]
Switch B 不需要重新回答:
这个 Packet 的最终逻辑目的地是谁?
因为 Switch A 已经告诉它了:
DGLORT = 0x4200Switch B 更关心:
0x4200 在我这一颗 ASIC 上应该如何实现?
这就是一种非常典型的:
Global Forwarding Decision
↓
Local Physical ResolutionFM10000 甚至可以完全根据 FTAG/GloRT 转发
这点非常有意思。
DPDK 对 FM10K 的说明明确写道:
在 FTAG Based Forwarding Mode 中,Switch Logic 根据 GloRT information 转发 Packet,而不是根据 MAC/VLAN Table。
也就是说:
普通 Ethernet forwarding
flowchart LR
P["Packet"]
P --> MAC["DMAC + VLAN"]
MAC --> TABLE["MAC Table"]
TABLE --> G["DGLORT"]
G --> PORT["Destination"]
FTAG forwarding
flowchart LR
P["Packet + FTAG"]
P --> G["DGLORT"]
G --> PORT["Destination"]
中间:
MAC Lookup可以被绕开。
这也是为什么 DPDK 把:
FTAG Based Forwarding
直接称为 FM10K 的一个 unique feature。
一个实际的 DPDK 例子
DPDK 官方 FTAG Test Plan 甚至保留了一组非常有价值的实际数据。
例如一个 FM10K 测试环境中:
Logical Port 4122
↓
GloRT 0x4000
Logical Port 4123
↓
GloRT 0x4200然后 DPDK 将这些值导出:
export PORT0_GLORT=0x4000
export PORT1_GLORT=0x4200再构造带有相应 FTAG 的 Packet,让硬件直接按照 GloRT 将 Packet 送往目标 Port。
这个例子非常能说明:
Logical Port ID
≠
GloRT
≠
Physical Port Number它们是三个不同层次的概念。
FM10000 中 DGLORT 是怎样产生的?
FM10000 的 DGLORT 不只是 L2 Lookup 产生。
Intel Datasheet 描述了完整的处理顺序:
flowchart LR
P["Parser"]
P --> FFU["FFU"]
FFU --> NH["NextHop"]
NH --> L2["L2 Lookup"]
L2 --> DM["DMASK Generation"]
DM --> TR["Triggers"]
TR --> SCH["Scheduler"]
SCH --> MOD["Modify / FTAG"]
其中 DGLORT 可以在多个 Stage 中产生或改变。
Step 1 — Parser
如果收到 FTAG:
DGLORT ← incoming FTAG否则:
DGLORT = 0Step 2 — FFU
FFU 可以执行:
SET_GLORT或者:
SET_ROUTEStep 3 — NextHop
Route/NextHop Lookup 可以得到新的:
DGLORTStep 4 — L2 Lookup
执行:
DMAC + EVIDlookup。
Hit:
MAC Entry → DGLORTMiss:
DGLORT = Flood GloRTStep 5 — DMASK Generation
将:
DGLORT转换成:
Physical Destination MaskStep 6 — Scheduler / MODIFY
最终如果 Packet 还要进入:
another FM10K
PCIe Host
Tunnel EngineMODIFY 可以把相应:
SGLORT
DGLORT重新放进 FTAG。
这套 DGLORT processing sequence 来自 Intel FM10000 Datasheet 的 Frame Processing architecture。
因此可以非常漂亮地概括成:
Parse
↓
Classify
↓
Route
↓
Bridge
↓
Resolve Logical Destination
↓
Resolve Physical Destination
↓
Schedule
↓
Carry Logical Destination ForwardfirstGlort 为什么会出现在 FM10K 软件里?
理解这些之后,再看到 FM10K SDK / Switch Software 中类似:
firstGlort这样的字段,就不会显得奇怪了。
GloRT 本身是一个:
16-bit Logical Fabric Namespace而不是简单的:
Physical Port Number因此软件往往需要为:
Physical Ports
PCIe PEPs
LAGs
Multicast Groups
Other Logical Endpoints分配不同 GloRT 范围。
所以像:
firstGlort = ...这种字段,更适合理解成:
某组 Fabric Resource 所使用的 GloRT Namespace / Range 的起始值。
而不是:
“第 5040 个物理端口”。
具体数值如何编码仍然取决于平台和 SDK 的 GloRT allocation policy,不能只根据一个 firstGlort 数值反推出 Physical Port。
最终可以把 FM10840 想象成这样
flowchart TB
RX["Packet"]
RX --> PARSER["Parser<br/>SGLORT / Incoming DGLORT"]
PARSER --> FLEX["FlexPipe"]
FLEX --> FFU["FFU"]
FFU --> NH["NextHop"]
NH --> L2["L2 Lookup"]
L2 --> DG["DGLORT"]
DG --> RESOLVE["GloRT Resolution"]
RESOLVE --> DMASK["Physical DMASK"]
DMASK --> SCH["Scheduler"]
SCH --> DEST{"Destination Type"}
DEST --> ETH["Ethernet"]
DEST --> PCI["PCIe Host"]
DEST --> TUN["Tunnel Engine"]
DEST --> FAB["Another Switch"]
PCI --> FT["FTAG"]
TUN --> FT
FAB --> FT
这样一来,前面几章也就真正串在了一起:
QDI
↓
How the circuits run
RapidArray
↓
How packets move
FlexPipe
↓
How packets are understood
GloRT
↓
How destinations are represented
FTAG
↓
How forwarding context moves across the fabric为什么 GloRT + FTAG 值得单独写?
因为它们揭示了 FM10K 最重要的设计特征之一:
Port 不再只是芯片边缘的一根 Ethernet SerDes。
在 FM10000 的世界里:
Physical Ethernet Port
PCIe Host Interface
Tunnel Engine
Remote ASIC Resource
LAG
Multicast Group都可以被抽象为某种:
Logical Fabric Resource
然后由:
GloRT标识,再通过:
FTAG把这种身份随着 Packet 在 Fabric 中传播。
所以如果必须用一句话总结:
GloRT decouples forwarding decisions from physical ports, while FTAG carries that logical forwarding context across FM10K fabric boundaries.
中文则可以概括成:
GloRT 将“转发到哪里”从物理端口编号中抽象出来,而 FTAG 则负责让这种逻辑转发上下文跨越交换芯片、PCIe Host 和 Tunnel Engine 继续存在。
也正是从这里开始,FM10840 已经很难再被简单称作“一颗 100G 网卡芯片”。
它更像是一颗:
拥有 PCIe Endpoint 的分布式 Ethernet Switch Fabric。
