AXI4 QoS 服务质量:AxQOS 信号、优先级/加权仲裁与互连 RTL 实现
更新时间:2026-09-25。本文是 AXI4 完整协议 的延伸:五通道、ID、burst 讲的是「事务怎么传」,这一篇讲「多个 master 抢一个从机端口时谁先传」。仲裁发生在 AXI Crossbar 内部,和 outstanding 与 ID 保序 一起决定系统的实际延迟与带宽分配。
本文要回答的问题
- AxQOS 信号长什么样,挂在哪条通道上,值大小代表什么?
- 读、写地址各有一组 QoS,互连是不是分别仲裁?
- 拿到 QoS 值以后,仲裁器内部怎么算:严格优先级、加权轮询、老化各是什么?
- 在互连 RTL 里实现 QoS 仲裁的具体写法是什么,有哪些坑?
- AXI5 在 QoS 上比 AXI4 多了什么?
一、为什么总线上需要 QoS
一颗典型 SoC 里,CPU 集群、DMA、显示子系统、NPU 都挂在同一条互连上,最终都要打到同一个 DDR 控制器端口。DDR 端口同一拍只能接受一个请求,于是必须有人做选择。如果仲裁完全公平(比如纯轮询),会出现两类问题:
- 关键路径延迟被拖垮:CPU 取指是延迟敏感的,它等一拍就是实打实的性能损失;而 DMA 搬大块数据对单拍延迟不敏感。公平轮询让两者同权,CPU 的 cache miss 被迫排在长 burst 后面。
- 实时流出现 underrun:显示/音频这类实时主设备需要保证带宽下限,被其他流量挤占就会花屏、爆音。
QoS(Quality of Service,服务质量)就是给每笔事务贴一个 4 位的「优先级标签」,让互连在冲突时能区分轻重缓急。举个有数字感的例子:一次 DDR cache miss 的片外往返可能在 80–120ns 量级,折合数百个核心周期;如果这笔读请求在互连仲裁处又被一个 16 拍突发的 DMA 写挡住,光是等待授权就再多十几个周期,CPU 流水线只能干等。反过来,DMA 晚十几个拍拿到授权几乎无感,因为它有足够深的 outstanding 队列把延迟掩盖掉。同样一拍授权,给两边带来的价值完全不同——这就是 QoS 存在的理由。
注意它不是实时性保证的全部:真正的带宽保证还要配合 outstanding 深度、burst 长度限制和 DDR 控制器自身的调度策略,AxQOS 只是互连在仲裁点能看到的那一个输入。把它当万能开关,调了 QoS 却不查缓冲深度,问题往往照旧。
二、AxQOS 信号机制
AXI4 协议里和 QoS 相关的信号只有两组,共 8 根线:
| 信号 | 位宽 | 所在通道 | 含义 |
|---|---|---|---|
AWQOS[3:0] | 4 | 写地址通道 AW | 这笔写事务的 QoS 值 |
ARQOS[3:0] | 4 | 读地址通道 AR | 这笔读事务的 QoS 值 |
| W / B / R 通道 | — | — | 没有任何 QoS 信号 |
协议对这个值的规定很克制,可以概括成四条:
- 4 位无符号整数,取值 0–15。协议推荐(recommend)数值越大优先级越高,但这不是强制语义——具体怎么解释完全由互连实现定义。
- 默认值为 0。不关心 QoS 的 master 直接恒接 0,行为退化成普通流量。
- 随地址相位一起发出,一笔事务一个值,整个 burst 期间不变;它不是可以中途修改的边带信号。
- 从机可以无视它。QoS 的解释点在互连:master 生成、interconnect 使用(也可以改写),slave 没有义务按它做事。
下图标出 QoS 在五通道中的位置——它只贴着两条地址通道流动,进入互连后被仲裁逻辑采样。
这张图同时说明一个推论:QoS 只能影响「这笔事务什么时候被放行」,一旦地址仲裁通过、路由建立,后续 W/R 拍就不再受 QoS 影响。这个时序细节在第六节会成为一个坑。
另外要把它和同样挂在地址通道上的 AxPROT[2:0] 区分开:PROT 是安全/特权属性,回答「谁在访问、能不能访问」;QoS 回答「该多快给它服务」。两者正交,不要混用。
三、读、写通道各自的 QoS
AWQOS 和 ARQOS 是两组独立信号,master 可以给同一个从机的读和写打上不同的值。这在工程上相当常见:
- CPU 的读(取指、load miss)通常比写(writeback 的脏行)延迟更敏感,很多实现给
ARQOS更高的默认值; - 反过来,视频采集设备的写是实时流(写不进 buffer 就丢帧),它的
AWQOS需要拉高。
Crossbar 内部的 AW 仲裁器和 AR 仲裁器因此也是两套独立逻辑,各自看各自的 QoS。但「独立仲裁」不等于「互不干扰」:两套仲裁的输出最终汇入同一个从机端口,从机端口的实际占用能力只有一份。典型处理是在端口出口再做一层读写统一调度(DDR 控制器通常倾向读优先,因为读阻塞会直接卡住发起方,而写通常有 buffer 垫底)。这层调度也要小心副作用:无条件读优先会让大块写流量长期退不下去,写 buffer 填满后反压反过来会卡住发起写的 master,最终间接堵住读。工程上的折中是写授权饥饿到一定拍数后强制插入一个写窗口,本质和第四节的老化是同一个思路。
还有一个协议细节值得点明:QoS 是逐笔事务有效的,不会被互连「记忆」。一个 master 前一笔填 12、下一笔填 0,仲裁器就按两笔各自的值分别对待,不存在「这个 master 整体是高优先级」的概念。想让某个主设备恒高优先级,要么在 master 侧固定接线,要么在互连入口做按端口的 QoS 覆写——后者更灵活,也是操作系统压制失控设备的抓手。
四、互连如何按 QoS 值仲裁
下图是本文的核心视角:多个 master 的地址请求先进各自的请求队列(或直接的 valid 信号),QoS 仲裁器每个周期选出一个获胜者,驱动到从机端口的 MUX。
图里的仲裁器要回答两个问题:QoS 不同时怎么办,QoS 相同时怎么办。常见策略有三种:
| 策略 | 规则 | 优点 | 风险 |
|---|---|---|---|
| 严格优先级 | QoS 值大的永远先赢 | 实现最简单,关键流量零等待 | 低 QoS 在持续高压下被饿死 |
| 加权轮询(WRR/赤字) | QoS 映射成权重,按权重分配授权比例 | 带宽比例可控,不饿死 | 单拍仍可能有等待,逻辑稍复杂 |
| 严格优先级 + 老化 | 等待越久优先级动态抬升 | 兼顾低延迟与防饥饿 | 需要年龄计数器,调参 |
纯严格优先级几乎只在流量明确不会持续饱和的系统里使用;成熟互连一般走后两种。下图展开一个「权重 + 老化」仲裁器的内部结构:每个输入先查 QoS→权重映射表得到信用额度,获胜一次扣一拍信用,信用耗尽本轮停权;同时年龄计数器给长期等待者加分,保证最终能赢。
加权轮询可以用一个数字例子理解。假设映射表规定 QoS=12 的权重为 3、QoS=4 的权重为 1,仲裁器每轮给前者 3 次授权、给后者 1 次。两边持续满载时,带宽大约按 3:1 切分,低权方每个调度轮次必然被服务一次,不存在无限等待;而在低权方空闲时,高权方可以拿走全部带宽,不像时分方案那样保留空槽。赤字(deficit)变体的改进是:没用完的额度可以结转,或者把权重解释成字节数而非授权次数,这样不同 burst 长度下的实际带宽比例仍然准确。
这里有一个容易被忽略的设计决策:QoS 值到调度行为的映射应当全系统统一。协议只说「大值推荐高优先级」,0–15 这 16 个档具体多重,完全是实现定义。实践中通常在互连里固化一张映射表(例如 0–3 为后台、4–7 为普通、8–11 为实时、12–15 为关键),由软件通过寄存器配置;各 master 的 QoS 赋值都要对照这张表,否则每个 IP 各填各的,QoS 就退化成随机数。映射表还应当支持运行时改写:系统进入待机、播放视频、跑推理计算等不同场景,流量结构完全不同,静态一套权重很难处处合理。
另一个常被忽视的粒度问题是单次 burst 的长度。QoS 只管「谁先开始」,管不了「开始以后占多久」。一笔 256 拍的长 burst 一旦获胜,哪怕第 3 拍来了 QoS=15 的紧急读,也要等到这笔 burst 结束。所以实时系统里通常对从机端口可见的单 burst 长度设上限(长传输由 master 拆成多个短 burst),把高优先级事务的最坏等待限制在「一个最长 burst」之内——这个上限要写进 master 的集成约束,而不是指望仲裁器临场打断。
五、互连 RTL 中的具体写法
下面给出一个可综合的仲裁器骨架(SystemVerilog,简化版)。核心要点:QoS 随请求寄存一拍、查映射表得到权重、配合信用计数与年龄做选择。
// 请求侧:QoS 随地址寄存,不把远端 master 的线直接拉进比较逻辑
logic [3:0] qos_q [N-1:0];
logic [N-1:0] req_q;
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin
req_q <= '0;
end else begin
for (int i = 0; i < N; i++)
if (req_valid[i] && req_ready[i]) begin
req_q[i] <= 1'b1;
qos_q[i] <= arqos[i]; // QoS 与请求一起锁存
end else if (grant[i] && port_fire) begin
req_q[i] <= 1'b0; // 端口实际放行后清除
end
end
// 有效优先级 = 静态权重(QoS 查表) + 年龄加分(饱和,防溢出)
logic [7:0] eff_prio [N-1:0];
always_comb
for (int i = 0; i < N; i++)
eff_prio[i] = {qos_q[i], 4'b0} + age_cnt[i];
// 组合选最大:用优先级编码器风格逐级比较,避免 for+break 锁存
always_comb begin
grant = '0;
winner = 0;
for (int i = 0; i < N; i++)
if (req_q[i] && (!req_q[winner] || eff_prio[i] > eff_prio[winner]))
winner = i;
grant[winner] = |req_q;
end授权发出后还有一步必须做:把获胜结果锁存,持续占用从机端口直到这笔 burst 的最后一拍。AXI 地址仲裁通过只代表首拍地址被接受,整笔 burst 可能跨越多个周期,期间端口路由不能换人,否则从机看到的 W 数据或 R 通道归属就会错乱。
骨架里两个实现细节值得多说一句。其一,年龄计数器要设饱和上限并在获胜后清零,否则宽度不够会回绕,老请求反而「变年轻」,老化形同虚设。其二,最终的最大值选择是组合逻辑,若输入路数多(16 路以上),级联比较本身就是一条可观的路径;可以先分组选出组内冠军、再在组间比较,做成树形两级结构,既缩短路径也便于后续插切片。权重表和老化参数建议做成软件可配寄存器,硅后调优时不用重新综合。
图中展示的正是第二节那个推论的落地:QoS 的作用边界是「事务之间」,不是「拍之间」。想支持拍级抢占需要额外的 interleaving 深度和 ID 管理,绝大多数从机(尤其 DDR 控制器)不支持,不要尝试。
六、AXI4 与 AXI5 在 QoS 上的差异
AXI5 保留了 AWQOS[3:0]/ARQOS[3:0] 两组 4 位信号和「大值高优先级」的推荐语义,但补了一个重要信号:QOS Valid(AWQV/ARQV)。在 AXI5 中,AxQOS 只有在对应的 QV 有效时才被互连采纳;QV 无效时,互连按缺省 QoS 处理该事务。这解决了 AXI4 里的一个含糊点:4'b0000 到底是「显式声明的最低优先级」还是「master 根本没提供 QoS」,在 AXI4 里无法区分,AXI5 用一根 valid 线把「没提供」和「提供了 0」分开。
两代的另一个差异是定位:AXI5 把 QoS 明确放进互连性能调节框架,配合其新增的事务子类型(如 stash、non-secure identity)使用;而 AXI4 的 QoS 描述更简略,大量行为依赖互连厂商自定义。跨代集成时注意:AXI4 master 接入 AXI5 互连,桥接处要补 QV;AXI5 master 降级到 AXI4 时,QV 信息只能丢弃,把缺省 QoS 直接绑成 0。信号命名与允许的组合以 AMBA 5 IHI0022 规约原文为准,移植前务必核对。
七、常见的坑
- 只做严格优先级、不做老化:高 QoS master 持续发流量时,低 QoS 设备授权计数长期为零,表现为偶发的寄存器访问超时,很难复现。
- 授权不锁存、每拍重新仲裁:burst 中途路由被高 QoS 事务抢走,W/R 拍串到另一笔事务上,从机协议状态机直接错乱。
- 读写各管各、出口不统一:AW 仲裁器把端口塞满写流量,AR 侧完全拿不到授权;要在从机端口做跨读写的统一调度。
- QoS 走远端组合路径参与比较:多个 master 的 4 位 QoS 比较串在授权关键路径上造成时序违例。解法是 QoS 随请求寄存(见第五节骨架),只比较本地锁存值,必要时再插 寄存器切片。
- QoS 与 ID 保序搅在一起:QoS 是事务间的调度权,不允许用来重排同一 ID 的在途事务;保序规则见 outstanding 与 ID 保序。
- 信任 master 自报的 QoS:任何 master 都能把自己标成 15。系统里要有软件配置的 QoS 覆写/钳位点,防止用户态或第三方 IP 自我提权挤占带宽。
- 映射表不统一:各 IP 按各自理解填 QoS 值,优先级体系名存实亡。QoS 档位划分要在 SoC 级定义并写进集成规范。
这一篇在知识体系里的位置
QoS 仲裁是 AXI Crossbar 与 Interconnect 的核心功能之一;信号基础(五通道、valid/ready)在 AXI4 完整协议 与 valid/ready 握手;QoS 影响不到的保序与死锁问题在 AXI4 outstanding 与 ID 保序;仲裁器自身的时序收敛在 AXI 寄存器切片;总线选型与 AXI/AXI5 的整体定位见 片上总线与 AMBA 协议;仲裁失当导致的挂死可参考 AXI 错误响应与总线超时。
总结
AXI4 QoS 服务质量就是写地址、读地址通道上各自一组 4 位的 AxQOS 标签(默认 0、大值推荐高优先级、解释权在互连);互连用严格优先级、加权轮询加老化来选获胜者,RTL 上必须寄存 QoS、锁存授权直到 burst 结束、并在从机端口统一读写调度;AXI5 额外引入 QOS Valid 区分「未提供」与「QoS=0」,跨代桥接时要补 QV,系统级还要统一档位映射并对自报 QoS 做覆写钳制。