共计 1320 个字符,预计需要花费 4 分钟才能阅读完成。
在地址译码、中断控制器等场景中,16- 4 编码器能将 16 个输入信号压缩为 4 位二进制编码,大幅简化电路复杂度。今天我们就来拆解这个数字电路基础组件,手把手教你用 Verilog 实现带优先级处理的工业级编码器。

真值表深度解析(含优先级机制)
优先级编码器的核心特点是:当多个输入同时有效时,只响应最高优先级的输入。假设 D15 优先级最高,D0 最低,其真值表关键特征如下:
- 输入 D[15:0] 中至少有一个为 1 时,输出 code[3:0] 对应最高有效位的二进制编码
- 所有输入为 0 时,valid 信号拉低表示无效状态
- 典型应用场景:键盘扫描电路(物理按键防抖处理)
示例片段(MSB 优先):
D15 D14 ... D0 | code3 code2 code1 code0 | valid
------------------------------------------------
1 X ... X | 1 1 1 1 | 1
0 1 ... X | 1 1 1 0 | 1
...
0 0 ... 0 | X X X X | 0
门级实现原理
实际硬件由三级逻辑构成:
- 优先级判断层:每个 Dn 输入会与比它更高优先级的取反信号相与(AND)
-
例如 D14 的使能信号 = D14 & ~D15
-
编码转换层:通过 OR 门将激活的优先级信号合并为 4 位二进制
-
code[3] = D15 | D14 | D13 | D12
-
valid 信号生成:所有输入进行或非(NOR)操作
SystemVerilog 实现
module priority_encoder_16_4 (input logic [15:0] din,
output logic [3:0] code,
output logic valid
);
always_comb begin
valid = |din; // 简写版或操作
casez (din) // casez 支持 z /? 通配符
16'b1???????????????: code = 4'b1111; // D15
16'b01??????????????: code = 4'b1110; // D14
16'b001?????????????: code = 4'b1101; // D13
// ... 省略中间 12 个 case
16'b0000000000000001: code = 4'b0000; // D0
default: code = 4'b0000; // 防御性设计
endcase
end
endmodule
避坑指南
- 锁存器预防
- 组合逻辑必须覆盖所有输入分支(使用 default)
-
推荐使用 always_comb 代替 always @(*)
-
未定义状态处理
- 实际电路可能存在亚稳态,建议添加同步复位
-
对关键路径添加时序约束:
set_max_delay -from [get_ports din] -to [get_ports code] 2.0 -
验证要点
- 必须测试相邻位同时激活的场景
- 验证全 0 输入时 valid 信号的跳变
思考题进阶
- 低电平有效改造方案:
- 输入端口添加取反操作:wire [15:0] active_low = ~din;
-
注意 valid 信号逻辑需要反向
-
AXI 总线集成要点:
- 需要寄存器打拍满足时序要求
- 考虑添加 ready/valid 握手信号
- 建议输出端添加流水线寄存器
通过这个实现过程,我们可以看到数字电路设计既需要理解硬件特性,又要掌握 HDL 编码规范。建议读者在 FPGA 开发板上实际验证这个编码器,观察信号跳变情况。
正文完
发表至: 未分类
近两天内
