Implementar lógica combinacional con bloque always de Verilog
El bloque always de Verilog sirve tanto para lógica secuencial como combinacional. Un artículo previo mostró ejemplos con assign. Aquí exploramos los mismos diseños usando always.
Ejemplo #1: Lógica combinacional simple
El código implementa lógica combinacional simple con salida z tipo reg que se actualiza cuando cualquier señal en lista de sensibilidad cambia. Lista declarada entre paréntesis tras @.
module combo (
input a, b, c, d, e,
output reg z
);
always @ ( a or b or c or d or e) begin
z = ((a & b) | (c ^ d) & ~e);
end
endmodule
El módulo combo se elabora en esquema hardware con puertas digitales.

=) al modelar lógica combinacional con alwaysTestbench
module tb;
reg a, b, c, d, e;
wire z;
integer i;
combo u0 ( .a(a), .b(b), .c(c), .d(d), .e(e), .z(z));
initial begin
a <= 0; b <= 0; c <= 0; d <= 0; e <= 0;
$monitor ("a=%0b b=%0b c=%0b d=%0b e=%0b z=%0b", a, b, c, d, e, z);
for (i = 0; i < 32; i = i + 1) begin
{a, b, c, d, e} = i;
#10;
end
end
endmodule
Salida (32 combinaciones):
ncsim> run a=0 b=0 c=0 d=0 e=0 z=0 a=0 b=0 c=0 d=0 e=1 z=0 a=0 b=0 c=0 d=1 e=0 z=1 ... a=1 b=1 c=1 d=1 e=1 z=1 ncsim: *W,RNQUIE: Simulation is complete.

assign como always se implementan en la misma lógica hardware.Ejemplo #2: Medio Sumador
module ha ( input a, b, output sum, cout);
always @ (a or b) begin
{cout, sum} = a + b;
end
endmodule

Testbench
module tb;
reg a, b;
wire sum, cout;
integer i;
ha u0 ( .a(a), .b(b), .sum(sum), .cout(cout));
initial begin
a <= 0; b <= 0;
$monitor("a=%0b b=%0b sum=%0b cout=%0b", a, b, sum, cout);
for (i = 0; i < 4; i = i + 1) begin
{a, b} = i;
#10;
end
end
endmodule
Salida:
ncsim> run a=0 b=0 sum=0 cout=0 a=0 b=1 sum=1 cout=0 a=1 b=0 sum=1 cout=0 a=1 b=1 sum=0 cout=1 ncsim: *W,RNQUIE: Simulation is complete.

Ejemplo #3: Sumador Completo
module fa ( input a, b, cin, output reg sum, cout);
always @ (a or b or cin) begin
{cout, sum} = a + b + cin;
end
endmodule

Testbench
module tb;
reg a, b, cin;
wire sum, cout;
integer i;
fa u0 ( .a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));
initial begin
a <= 0; b <= 0;
$monitor("a=%0b b=%0b cin=%0b cout=%0b sum=%0b", a, b, cin, cout, sum);
for (i = 0; i < 8; i = i + 1) begin
{a, b, cin} = i;
#10;
end
end
endmodule
Salida:
ncsim> run a=0 b=0 cin=0 cout=0 sum=0 a=0 b=0 cin=1 cout=0 sum=1 a=0 b=1 cin=0 cout=0 sum=1 a=0 b=1 cin=1 cout=1 sum=0 a=1 b=0 cin=0 cout=0 sum=1 a=1 b=0 cin=1 cout=1 sum=0 a=1 b=1 cin=0 cout=1 sum=0 a=1 b=1 cin=1 cout=1 sum=1 ncsim: *W,RNQUIE: Simulation is complete.

Ejemplo #4: Multiplexor 2x1
module mux_2x1 (input a, b, sel, output reg c);
always @ ( a or b or sel) begin
c = sel ? a : b;
end
endmodule

Testbench
module tb;
reg a, b, sel;
wire c;
integer i;
mux_2x1 u0 ( .a(a), .b(b), .sel(sel), .c(c));
initial begin
a <= 0; b <= 0; sel <= 0;
$monitor("a=%0b b=%0b sel=%0b c=%0b", a, b, sel, c);
for (i = 0; i < 3; i = i + 1) begin
{a, b, sel} = i;
#10;
end
end
endmodule
Salida:
ncsim> run a=0 b=0 sel=0 c=0 a=0 b=0 sel=1 c=0 a=0 b=1 sel=0 c=1 ncsim: *W,RNQUIE: Simulation is complete.

Ejemplo #5: Demultiplexor 1x4
module demux_1x4 (
input f,
input [1:0] sel,
output reg a, b, c, d
);
always @ ( f or sel) begin
a = f & ~sel[1] & ~sel[0];
b = f & sel[1] & ~sel[0];
c = f & ~sel[1] & sel[0];
d = f & sel[1] & sel[0];
end
endmodule

Testbench
module tb;
reg f;
reg [1:0] sel;
wire a, b, c, d;
integer i;
demux_1x4 u0 ( .f(f), .sel(sel), .a(a), .b(b), .c(c), .d(d));
initial begin
f <= 0; sel <= 0;
$monitor("f=%0b sel=%0b a=%0b b=%0b c=%0b d=%0b", f, sel, a, b, c, d);
for (i = 0; i < 8; i = i + 1) begin
{f, sel} = i;
#10;
end
end
endmodule
Salida:
ncsim> run f=0 sel=0 a=0 b=0 c=0 d=0 f=0 sel=1 a=0 b=0 c=0 d=0 f=0 sel=10 a=0 b=0 c=0 d=0 f=0 sel=11 a=0 b=0 c=0 d=0 f=1 sel=0 a=1 b=0 c=0 d=0 f=1 sel=1 a=0 b=0 c=1 d=0 f=1 sel=10 a=0 b=1 c=0 d=0 f=1 sel=11 a=0 b=0 c=0 d=1 ncsim: *W,RNQUIE: Simulation is complete.

Ejemplo #6: Decodificador 4x16
module dec_3x8 (
input en,
input [3:0] in,
output reg [15:0] out
);
always @ (en or in) begin
out = en ? 1 << in: 0;
end
endmodule

Testbench
module tb;
reg en;
reg [3:0] in;
wire [15:0] out;
integer i;
dec_3x8 u0 ( .en(en), .in(in), .out(out));
initial begin
en <= 0; in <= 0;
$monitor("en=%0b in=0x%0h out=0x%0h", en, in, out);
for (i = 0; i < 32; i = i + 1) begin
{en, in} = i;
#10;
end
end
endmodule
Salida:
ncsim> run en=0 in=0x0 out=0x0 ... en=1 in=0x0 out=0x1 en=1 in=0x1 out=0x2 ... en=1 in=0xf out=0x8000 ncsim: *W,RNQUIE: Simulation is complete.

Verilog
- Monitorización precisa de temperatura en armario de servidores con Raspberry Pi
- Circuito con interruptor: guía práctica de circuitos eléctricos básicos
- Circuitos integrados: Fundamentos de puertas lógicas digitales
- Controladores lógicos programables (PLC): control digital moderno para sistemas industriales
- Comprender el álgebra booleana: de fundamentos lógicos a circuitos digitales
- Dominando Multiplicación y División con Notación Científica
- Industria 4.0: Preguntas y respuestas con Verena Majuntke de Bosch.IO sobre IoT, automatización y la fábrica del futuro
- Logre acabados perfectos con las rectificadoras de precisión Okamoto
- Dominando VHDL y Verilog: Escribiendo lógica combinacional y secuencial limpia
- Diseño práctico a nivel de puertas en Verilog: Puertas AND, OR, NOT y Multiplexor 2x1
- Dominar $timeformat en Verilog: Control de precisión y visualización