Multiplexor 4-a-1 en Verilog: Diseño e Implementación
¿Qué es un mux o multiplexor?
Un multiplexor o mux es un elemento digital que transfiere datos de una de las N entradas a la salida basándose en la señal de selección. El caso mostrado es N=4. Por ejemplo, un multiplexor de 4 bits tendría N entradas cada una de 4 bits donde cada una puede transferirse a la salida mediante la señal de selección.
sel es una entrada de 2 bits con cuatro valores posibles. Cada valor en la línea de selección permite que una de las entradas vaya al pin de salida 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
Un multiplexor 4x1 puede implementarse de varias formas; aquí veremos las dos más comunes:
- Usando sentencia
assign - Usando sentencia
case
Usando sentencia 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
);
// Cuando sel[1] es 0, se selecciona (sel[0]? b:a); cuando es 1, (sel[0]? d:c)
// Cuando sel[0] es 0, a va a salida; sino b. Cuando sel[0] es 0, c va a salida; sino d
assign out = sel[1] ? (sel[0] ? d : c) : (sel[0] ? b : a);
endmodule
El módulo mux_4x1_assign tiene cuatro entradas de datos de 4 bits, una selección de 2 bits y una salida de 4 bits. El multiplexor selecciona a, b, c o d basándose en sel usando assign.
Usando sentencia case
La señal out se declara como reg porque se usa en un bloque procedural como 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
);
// Este bloque always se ejecuta cuando a/b/c/d/sel cambian
// Según valor en sel, salida se asigna a 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
El módulo mux_4x1_case tiene las mismas entradas/salidas. Selecciona a, b, c o d basándose en sel usando case.
Esquema Hardware
Ambos modelos se sintetizan en el mismo hardware.
Testbench
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;
// Instanciar diseño con case statement
mux_4to1_case mux0 ( .a (a), .b (b), .c (c), .d (d), .sel (sel), .out (out));
// Bloque initial como estímulo
initial begin
$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. Tiempo 0: valores aleatorios a/b/c/d, sel=0
sel <= 0; a <= $random; b <= $random; c <= $random; d <= $random;
// 2. Cambiar sel cada 5ns
for (i = 1; i < 4; i=i+1) begin #5 sel <= i; end
// 3. Esperar 5ns y finalizar
#5 $finish;
end
endmodule
Registro de simulación
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 La simulación finalizó vía $finish(1) en el tiempo 20 NS + 0
Verilog
- Dominar Verilog: Tutorial completo para diseño de circuitos digitales
- Dominar la concatenación en Verilog: Guía práctica
- Comprender las asignaciones en Verilog: tipos, sintaxis y mejores prácticas
- Bloqueante vs. No bloqueante en Verilog: Diferencias clave explicadas
- Dominar las funciones en Verilog para diseño RTL eficiente
- Comprender las Tasks en Verilog: Funciones vs Tasks, sintaxis y uso
- Generador de reloj en Verilog: Guía de diseño e implementación
- Dominar las funciones matemáticas en Verilog para diseño de hardware eficiente
- Dominar $timeformat en Verilog: Control de precisión y visualización
- Comprender e imprimir timescales de Verilog en cualquier alcance
- Dominando la E/S de Archivos en Verilog: Abrir, Leer, Escribir y Cerrar