Round-Robin 仲裁器:公平轮转、优先级编码与固定优先级饥饿
更新时间:2026-09-19。仲裁器是 AXI Crossbar 每个从机端口、DMA 和片上网络(NoC)的共用部件。基础 one-hot/轮询概念见入门 onehot 与轮询。
本文要回答的问题
- 固定优先级仲裁为什么会饿死低优先级?
- Round-Robin 怎么做到「人人有份」,mask 旋转如何实现?
- 授权后指针怎么更新?被授权方这一轮还能不能再中?
- 想给某通道更高份额怎么办(加权/赤字)?
一、固定优先级:简单但会饿死
最基础的是优先级编码器:输入 req[N-1:0],编号越大(或越小)优先级越高,输出一个 grant one-hot:
// 位 0 优先级最高
assign gnt[0] = req[0];
assign gnt[1] = req[1] & ~req[0];
assign gnt[2] = req[2] & ~req[1] & ~req[0];
// ...问题:若高优先级通道持续请求,低优先级通道永远拿不到授权(starvation,饥饿)。适合能确证高流量源不会常驻、或天然有严格优先(如实时/安全中断)的场合。
二、Round-Robin:授权后旋转优先级
RR 的思想:谁刚被服务,谁的优先级就降到最低,下一轮从「它后面那一位」开始优先。这样只要各源持续请求,授权机会严格轮转,无人能长期独占。
实现常用 mask 法:维护一个 mask(或优先级指针),分两步找胜者:
- 在「mask 之内/之后」的请求里找最低置位(高优先段);
- 若该段没有请求,再在全部请求里找最低置位(回绕段);
- 两段结果合成 grant,授权完成后把 mask 更新为「胜者的下一位」。
// 求一个向量里优先级最高(最低位)置位:标准 priority encoder
// masked: 只在 mask 指定起点及之后看请求
wire [N-1:0] masked_req = req & mask;
wire [N-1:0] g1 = prio_enc(masked_req); // 高优先段
wire [N-1:0] g2 = prio_enc(req); // 回绕段(全量)
wire [N-1:0] grant = (g1 != 0) ? g1 : g2;
always @(posedge clk) if (accept) begin
mask <= {grant[N-2:0], 1'b0}; // 胜者下一轮起点 = grant 左移一位
endprio_enc 可以用「x & (~x+1)」保留最低置位(one-hot)再编码,或用并行前缀/进位链快速实现。one-hot 指针版本则直接维护「当前最高优先位」one-hot,用旋转 MUX 重排请求顺序再过固定优先级编码器,结构更规整、易跑高频。
三、授权保持与 valid/ready 反压
总线上一次授权往往要持续到该笔事务真正被接受:
- grant 应在
req & grant & ready(握手完成)时才推进指针;若下游没 ready,授权必须保持给同一请求方,不能在反压期间轮转给别人,否则事务身份错乱。 - 多拍 burst:通常一次授权覆盖整个 burst(不可在中途切主),或在 AXI 里对每个通道独立授权。五通道独立仲裁见 Crossbar。
- 请求寄存器化:组合 req→grant 路径长时打一拍,配合 skid buffer 收敛时序(见 寄存器切片)。
四、加权与赤字:不想「绝对平均」时
纯 RR 给每个持续源相等带宽。要差异化份额:
- 加权轮询(WRR):一轮里给高权重通道多次「虚拟授权槽」(权重 3 的源在长度 Σweight 的服务表里占 3 格)。
- 赤字轮询/赤字公平队列(DRR):每轮给每队列一个配额,攒到的字节/拍数不超过配额才发送,用不完的配额可累积,实现按「字节数」而非「包数」公平。
- 严格优先级 + RR 混合:高优先级类用抢占/绝对优先,同类内 RR;但必须给低类加老化(aging)——等待越久临时优先级越高,从机制上封顶最长等待,杜绝饥饿。
- NoC 里常用 round-robin + matrix arbiter(矩阵仲裁器,严格「距离上次授权最久者优先」,公平性可证明),见 NoC 路由器。
五、公平性、面积与时序权衡
| 实现 | 公平性 | 关键路径 | 面积 | 适用 |
|---|---|---|---|---|
| 固定优先级 | 会饿死 | 短 | 最小 | 源不常驻/强实时 |
| RR mask 旋转 | 长期均等 | 中(两级 PE) | 小 | 总线/DMA 主流 |
| RR one-hot 指针 + 旋转 MUX | 均等 | 规整、可流水 | 中 | 高频宽 Crossbar |
| 矩阵仲裁器 | 严格 LRU 公平 | 较长 | O(N²) | NoC、QoS |
| WRR/DRR | 按权重/字节 | 中 | 中-大 | 多 QoS、带宽分配 |
六、常见的坑
- 下游没 ready 就轮转:授权在握手前切换,事务被张冠李戴;必须握手成功再更新指针。
- burst 中途切主:通道在一笔事务中间换人,协议违例;一次授权绑定到 last。
- mask 更新用组合 grant 又被复位打乱:复位后 mask 应全 1(允许从 bit0 开始)或显式指定起点,避免上电死锁某几位。
- 只有一个源时也旋转:不影响正确性但可能让时序/功耗变差,可在无竞争时直通。
- 多通道共用一个仲裁结果:AXI 五通道若共享 grant 会失去并行甚至死锁,需独立仲裁。
- 公平=带宽公平的误解:纯 RR 公平的是「拍/事务数」,包长不同时实际字节带宽并不均等,要字节公平用 DRR。
相关与延伸
系统应用见 AXI Crossbar、DMA 控制器、NoC 路由器;握手配合见 valid/ready 握手;入门概念见 onehot 与轮询;时序见 寄存器切片。
总结
仲裁器在固定优先级(简单但持续高优先会饿死低优先)与 Round-Robin(授权后用 mask/one-hot 指针把胜者优先级转到最低、长期严格均等)之间取舍;指针只能在握手成功、且一笔事务到 last 后才推进,反压期间授权保持;要差异化带宽用 WRR/DRR、要可证明的等待公平用矩阵仲裁器加老化,AXI 五通道则必须各自独立仲裁。