亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Verilog

Verilog 4 选 1 多路选择器:设计与实现

什么是多路选择器?

多路选择器(mux)是一种数字元件,根据选择信号将 N 个输入中的一个传送到输出。下例中 N=4。例如 4 位多路选择器有 4 个 4 位输入,每个输入可通过选择信号传送到输出。

sel 为 2 位输入,可取四个值。选择线上的每个值允许一个输入传送到输出引脚 out。

sel a b c d out
0   3 7 1 9 3
1   3 7 1 9 7
2   3 7 1 9 1
3   3 7 1 9 9

4x1 多路选择器可用多种方式实现,这里展示两种最常用方式:

使用 assign 语句

module mux_4to1_assign ( 
  input [3:0] a, 
  input [3:0] b, 
  input [3:0] c, 
  input [3:0] d, 
  input [1:0] sel, 
  output [3:0] out
); 
  // 当 sel[1] 为 0 时选择 (sel[0]? b:a),为 1 时选择 (sel[0]? d:c)
  // 当 sel[0] 为 0 时输出 a,否则 b;当 sel[0] 为 0 时输出 c,否则 d
  assign out = sel[1] ? (sel[0] ? d : c) : (sel[0] ? b : a); 
endmodule 

模块 mux_4x1_assign 有四个 4 位数据输入、一个 2 位选择输入和一个 4 位数据输出。多路选择器根据选择信号 sel 使用 assign 语句选择 a、b、c 或 d。

使用 case 语句

注意信号 out 声明为 reg 类型,因为它用在 always 等 过程 块中。

module mux_4to1_case ( 
  input [3:0] a, 
  input [3:0] b, 
  input [3:0] c, 
  input [3:0] d, 
  input [1:0] sel, 
  output reg [3:0] out
); 
  // 此 always 块在 a/b/c/d/sel 任一变化时执行
  // 根据 sel 值将输出赋值为 a/b/c/d
  always @ (a or b or c or d or sel) begin 
    case (sel) 
      2'b00 : out <= a; 
      2'b01 : out <= b; 
      2'b10 : out <= c; 
      2'b11 : out <= d; 
    endcase 
  end 
endmodule 

模块 mux_4x1_case 同样有四个 4 位数据输入、一个 2 位选择输入和一个 4 位数据输出。多路选择器根据选择信号 sel 使用 case 语句选择 a、b、c 或 d。

硬件原理图

两种建模方式综合后得到相同硬件结构,如下图所示。

测试平台

module tb_4to1_mux; 
  reg [3:0] a; 
  reg [3:0] b; 
  reg [3:0] c; 
  reg [3:0] d; 
  wire [3:0] out; 
  reg [1:0] sel; 
  integer i; 
  // 实例化其中一种设计,这里用 case 语句版本
  mux_4to1_case mux0 ( 
    .a (a), .b (b), .c (c), .d (d), .sel (sel), .out (out)
  ); 
  // 激励块
  initial begin 
    // 后台启动监视器,在 a/b/c/d/sel/out 变化时显示值
    $monitor ("[%0t] sel=0x%0h a=0x%0h b=0x%0h c=0x%0h d=0x%0h out=0x%0h", $time, sel, a, b, c, d, out); 
    // 1. 时间 0 驱动随机值给 a/b/c/d,保持 sel = 0
    sel <= 0; 
    a <= $random; b <= $random; c <= $random; d <= $random; 
    // 2. 每 5ns 改变 sel 值
    for (i = 1; i < 4; i=i+1) begin 
      #5 sel <= i; 
    end 
    // 3. 步骤 2 结束后等待 5ns 结束仿真
    #5 $finish; 
  end 
endmodule 

仿真日志

ncsim> run
[0] sel=0x0 a=0x4 b=0x1 c=0x9 d=0x3 out=0x4
[5] sel=0x1 a=0x4 b=0x1 c=0x9 d=0x3 out=0x1
[10] sel=0x2 a=0x4 b=0x1 c=0x9 d=0x3 out=0x9
[15] sel=0x3 a=0x4 b=0x1 c=0x9 d=0x3 out=0x3
Simulation complete via $finish(1) at time 20 NS + 0

Verilog

  1. Verilog 入门:数字电路设计完整教程
  2. 掌握 Verilog 拼接操作:实用指南
  3. 深入理解 Verilog 赋值语句:类型、语法与最佳实践
  4. Verilog阻塞与非阻塞赋值:关键区别详解
  5. 掌握Verilog函数:高效RTL设计的复用利器
  6. 理解Verilog任务:函数vs任务、语法与用法全解析
  7. Verilog 时钟发生器设计与实现指南
  8. 掌握 Verilog 数学函数:高效硬件设计的利器
  9. 掌握 Verilog $timeformat:精度控制与显示格式化
  10. 理解与打印 Verilog 任意作用域下的 Timescale
  11. 掌握 Verilog 文件 I/O:打开、读取、写入和关闭
  12. Verilog 入门指南:Hello World 示例