优先级编码器与先行链:多个请求同时来谁说了算
更新时间:2026-09-12。本文是「集成电路大类 · 芯片设计」入门层(beginner)数字逻辑基础第三十四篇。普通编码器假设「同一时刻只有一个输入」,但中断线、DMA 请求、总线主设备常常同时拉起好几个。这一篇讲电路如何按「高优先级胜出」选出编号,以及怎么把它做快。
本文要回答的问题
- 普通编码器遇到两个输入同时有效会怎样?优先级编码器怎么规定胜负?
- valid(有没有请求)信号为什么必须有?
- 串行优先链(ripple)为什么省面积却慢?怎么用「组有没有更高请求」做先行/树形扩展?
- 优先级编码器和「找最高位的 1(leading-one / LZC)」为什么是同一电路?
- 它在中断控制器、仲裁器、浮点对阶里分别干什么?
一、先有约定:编号越大优先级越高
给 8 个请求 req[7:0],规定编号越大优先级越高,输出最高的那个有效位的二进制编号,外加一个 valid(至少有一个请求)。真值表的关键几行:
| req(二进制) | 最高有效位 | y[2:0] | valid |
|---|---|---|---|
| 00000000 | 无 | 000 | 0 |
| 00000001 | 0 | 000 | 1 |
| 00000110 | 2 | 010 | 1 |
| 10010000 | 7 | 111 | 1 |
注意「无请求」必须用 valid=0 单独表达,否则会和「请求 0 有效」混淆。这正是中断控制器里「中断号 + 有无中断」、以及 FPU 里「指数/尾数是否为 0」都要带使能的原因。
二、两种结构:串行优先链 vs 并行/树形先行
串行优先链:从最低位开始逐级传一个「比我更高位是否已有请求」的信号。
// 行为写法,综合器据此生成优先逻辑(等价于 if 先写高优先级)
always_comb begin
y = '0; valid = |req;
for (int i=0; i<W; i++)
if (req[i]) y = i; // 循环到最高的 i 会覆盖,故高位胜
end电路上它是一条链:每一级看「更高位有没有 1」,有就屏蔽自己。位宽大时,这条「有没有更高请求」的信号要逐级穿过去,延迟随 W 线性增长——和行波进位加法器的进位链是同一类瓶颈。
并行/先行(fast priority):模仿超前进位,先把位分成若干组,每组用归或快速算出「本组有没有 1」和「本组最高 1 在组内第几」,再用组级先行信号判断「更高的组有没有请求」,两级组合即可定位。这正是一棵前导 1 检测(leading-one detect)/前导零计数 LZC 树,延迟降到 O(log W)。
三、一个电路,多个名字:LZC 与 leading-one
把优先级编码器的输入看成一个二进制数,「输出最高有效 1 的编号」就是前导零计数(count leading zeros / leading-one position)。同一结构在不同场合名字不同、用途不同:
| 场合 | 输入 | 用途 |
|---|---|---|
| 中断/DMA 控制器 | 多条请求线 | 选最高优先级中断号给 CPU |
| 总线仲裁 | one-hot 请求 | 固定优先级选主;配合掩码做 round-robin |
| 浮点对阶/规格化 | 尾数 | 找最高有效 1 确定移位量和指数(见浮点) |
| 除法/归一化 | 被除数 | 移位相减前定位,见除法器 |
固定优先级 vs 轮询:纯优先级编码器永远偏向高编号(固定优先级),会让低请求在高请求持续时饿死。公平的 round-robin 用一个「当前最高优先级」掩码循环旋转赢家位置,硬件上就是「优先级编码器 + 旋转/屏蔽」,详见 one-hot 与 round-robin。
四、可综合写法与坑
- 行为上用「从低到高遍历、命中即赋值、后写覆盖」或
for反向break式写法表达优先级,综合器会生成优先链;宽而时序紧时显式分组或用casez/并行归或帮它做先行; - 中断/请求若来自别的时钟域,进优先级编码器前要先各自同步(脉冲类用握手/边沿同步),否则可能采到毛刺造成误中断(CDC);
- 组合
always里y、valid必须在所有分支都赋值,避免意外锁存器; - 输出编号位宽用
$clog2(W),无请求时编号无意义、必须靠valid判定。
与现有篇目的衔接
总结
一句话总结:普通编码器假设同时只有一个输入有效,优先级编码器则规定高编号胜出、输出最高有效请求的编号,并用一个 valid 专门表达「到底有没有请求」(否则与 0 号请求混淆);它的串行实现是一条「更高位是否已有 1」的优先屏蔽链,省面积但延迟随位宽线性增长,快速实现仿照超前进位分组归或、做成 O(log W) 的前导 1/LZC 树;这个「找最高位 1」的电路一身多名——在中断/DMA 里选中断号、在仲裁里选总线主、在浮点对阶和除法规格化里定移位量;纯优先编码是固定优先级、会饿死低请求,公平的 round-robin 靠掩码旋转赢家位置实现;用时注意跨域请求先同步、组合逻辑全覆盖、编号宽度取 clog2。