多路选择器设计
什么是译码器
数字电路中,译码器是一种多输入多输出的组合逻辑电路,将输入的二进制代码转换为特定的输出信号。这些输出信号通常对应着代码特定的含义或者状态。译码器在数字系统中广泛应用,例如在显示器、存储器、编码器等设备中。
译码器的分类
译码器可以分为二进制译码器和BCD译码器。
-
二进制译码器:二进制译码器将n位二进制输入转换为2^n个输出。每个输出对应一个特定的二进制代码。二进制译码器可以分为普通二进制译码器和优先级二进制译码器。
-
BCD译码器:BCD译码器将4位BCD码转换为10个输出,每个输出对应一个十进制数字。
译码器的应用
最常见的变量译码器为3-8译码器,主要用于端口的扩展。假如我们有8个led灯需要单独控制,理论上我们需要用8个I/O口,普通的单片机也够用,但是如果我们控制的不是8个led灯,而是一个点阵屏,那就可想而知我们要使用的I/O口数量不是一般控制器就能满足的了,即便是I/O资源丰 富的FPGA在面对巨大的点阵屏时也可能面临管脚资源不够用的尴尬境地。此种情况下使用3-8译码器就可以很好的解决这个问题,我们可以通过控制器控制3个I/O输出的8种情况来分别控制8个输出状态,相当于用3个I/O口就可以独立控制8个led灯,即一个3-8译码器就能够节约出来5个I/O口,算起来是相当合算 的。现在的3-8译码器大都做成了独立ASIC芯片,价格也往往非常便宜。
译码器的工作原理是什么
译码器的结构:通常有N位输入和2^N个输出。
- 输入端(Input):接收二进制代码,例如,一个 3 位二进制译码器有 3 个输入端。
- 输出端(Output):输出对应于输入的二进制代码,例如,一个 3 位二进制译码器有 8 个输出端。
- 使能端(Enable):使能端用于控制译码器的输出,当使能端为高电平时,译码器正常工作,当使能端为低电平时,译码器输出为0。
- 使能端可以用于译码器的扩展(用多个小译码器构成一个大译码器)或控制译码器的工作状态。
译码器的Verilog设计
设计定义
- 设计一个3-8译码器
- 用3-8译码器构成一个4-16译码器
设计目的
- 掌握组合逻辑电路的描述方式
- 掌握always语句描述组合逻辑的敏感列表
- 掌握case语句的用法
- 掌握case语句缺省条件的重要性,避免组合逻辑种产生锁存器
- 掌握Verilog的三种描述方式——行为级描述、结构级描述、数据流级描述
设计实现
设计思路
- 3-8译码器设计思路:本质上就是一个多路选择器,根据输入的二进制代码,选择对应的输出。
- 4-16译码器设计思路:用3-8译码器构成一个4-16译码器。
3-8译码器模块和端口定义

| 端口名称 | 端口方向 | 端口位宽 | 端口说明 |
|---|---|---|---|
| sel | input | 3 | 3位二进制输入 |
| en | input | 1 | 使能端 |
| out | output | 8 | 8位二进制输出 |
3-8译码器接口时序/真值表
sel = 000, en = 1, out = 00000001
sel = 001, en = 1, out = 00000010
sel = 010, en = 1, out = 00000100
sel = 011, en = 1, out = 00001000
sel = 100, en = 1, out = 00010000
sel = 101, en = 1, out = 00100000
sel = 110, en = 1, out = 01000000
sel = 111, en = 1, out = 10000000
3-8译码器设计
`timescale 1ns/1ns
module decoder3_8(
input [2:0] sel,
input en,
output [7:0] out
);
reg [7:0] out_temp;
always @(*)begin
case(sel[2:0])
3'b000 : out_temp = 8'b0000_0001;
3'b001 : out_temp = 8'b0000_0010;
3'b010 : out_temp = 8'b0000_0100;
3'b011 : out_temp = 8'b0000_1000;
3'b100 : out_temp = 8'b0001_0000;
3'b101 : out_temp = 8'b0010_0000;
3'b110 : out_temp = 8'b0100_0000;
3'b111 : out_temp = 8'b1000_0000;
default : out_temp = 8'b0000_0000;
endcase
end
assign out = en ? out_temp : 8'b0000_0000;
endmodule
3-8译码器功能仿真

4-16译码器模块和端口定义

| 端口名称 | 端口方向 | 端口位宽 | 端口说明 |
|---|---|---|---|
| sel | input | 4 | 4位二进制输入 |
| en | input | 1 | 使能端 |
| out | output | 16 | 16位二进制输出 |
4-16译码器verilog设计
`timescale 1ns/1ns
module decoder4_16(
input [3:0] sel,
input en,
output [15:0] out
);
wire en_u0;
wire en_u1;
assign en_u0 = ~sel[3] & en;
assign en_u1 = sel[3] & en;
decoder3_8 decoder3_8_u0(
.sel(sel[2:0]),
.en(en_u0),
.out(out[7:0])
);
decoder3_8 decoder3_8_u1(
.sel(sel[2:0]),
.en(en_u1),
.out(out[15:8])
);
endmodule
4-16译码器RTL分析

4-16译码器功能仿真

Implement

问题记录和解决
-
问题描述: 对4-16译码器的仿真中,当sel信号从1111跳变到0000时,out[7]产生了毛刺;当sel信号从0111跳变到1000时,out[15]产生了毛刺。
-
问题原因
- 组合逻辑传播延迟不一致 4到16译码器是纯组合逻辑电路,当sel信号发生变化时,内部各个门电路的传播延迟不完全相同,导致输出信号在短时间内出现错误的中间状态。
- 多位信号同时变化导致的竞争冒险 例如当sel从4’b0111(7)变化到4’b1000(8)时: sel[3]从0→1 sel[2:0]从111→000 由于各位信号的传播延迟略有差异,可能会短暂出现4’b0000或4’b1111等中间状态,从而激活错误的输出。
-
验证: 修改testbench,在sel信号从1111跳变到0000时,改为从1111跳变到1110,避免同时出现三位及以上的变化。再次仿真,发现out[7]和out[15]不再产生毛刺。
-
解决办法: 波形中的毛刺是组合逻辑电路的正常现象,通常不会影响电路的功能正确性。如果在实际应用中需要避免毛刺,可以考虑添加同步逻辑或使用特殊的编码方式(如格雷码,每次只有一位发生变化,可以减少毛刺)。对于当前的仿真测试,这些毛刺不会影响译码器功能的验证。