Contador de 4 Bits: Conteo Binario Eficiente de 0 a 15
El contador de 4 bits incrementa desde 4'b0000 hasta 4'h1111 y luego vuelve a 4'b0000. Seguirá contando mientras se proporcione un reloj en ejecución y el reset se mantenga alto.
El desbordamiento ocurre cuando el bit más significativo de la suma final se descarta. Cuando el contador está en su valor máximo 4'b1111 y recibe una solicitud de conteo más, intenta alcanzar 5'b10000, pero al soportar solo 4 bits, el MSB se descarta resultando en 0.
0000 0001 0010 ... 1110 1111 desborda 0000 0001 ...
El diseño contiene dos entradas: una para el reloj y otra para un reset activo-bajo. Un reset activo-bajo reinicia el diseño cuando el pin de reset vale 0. Hay una salida de 4 bits llamada out que proporciona los valores del contador.
Diseño del Contador Electrónico
module counter (
input clk, // Puerto de entrada para reloj
input rstn, // Puerto de entrada para reset activo-bajo
output reg[3:0] out // Puerto de salida de 4 bits para valores del contador
);
// Este bloque always se dispara en el flanco positivo de clk (0->1)
// Verifica si reset es 0; si sí, pone out a cero
// Si reset es 1, permite contar, incrementa contador
always @ (posedge clk) begin
if (! rstn) out <= 0;
else out <= out + 1;
end
endmodule
El module counter tiene reloj y reset activo-bajo (denotado por n) como entradas y el valor del contador como salida de 4 bits. El bloque always se ejecuta siempre que el reloj transiciona de 0 a 1 (flanco positivo). La salida se incrementa solo si reset está alto (1), logrado por el bloque if-else. Si reset está bajo en el flanco positivo, la salida se reinicia a 4'b0000.
Testbench
Podemos instanciar el diseño en nuestro módulo testbench para verificar que el contador funciona como se espera.
El módulo testbench se llama tb_counter y no requiere puertos al ser el módulo superior en simulación. Necesitamos variables internas para generar, almacenar y conducir reloj y reset. Declaramos dos variables reg para reloj y reset, y un wire para conectar con la salida del diseño.
El reloj se genera vía bloque always con período de 10 unidades de tiempo. El bloque initial establece valores iniciales y conduce el reset. El diseño se instancia en el testbench y se conecta a nuestras variables internas. No hay sentencias $display, así que no veremos mensajes en consola.
module tb_counter;
reg clk; // Variable interna TB para conducir reloj al diseño
reg rstn; // Variable interna TB para conducir reset activo-bajo
wire [3:0] out; // Wire para conectar con salida del diseño
// Instanciar diseño counter y conectar con variables TB
counter c0 (
.clk (clk),
.rstn (rstn),
.out (out)
);
// Generar reloj para el diseño
// Este reloj invierte su valor cada 5ns -> período = 10ns -> freq = 100 MHz
always #5 clk = ~clk;
// Este bloque initial forma el estímulo del testbench
initial begin
// 1. Inicializar variables TB a 0 al inicio
clk <= 0;
rstn <= 0;
// 2. Conducir resto del estímulo, reset se aserta en medio
#20 rstn <= 1;
#80 rstn <= 0;
#50 rstn <= 1;
// 3. Finalizar estímulo tras 200ns
#20 $finish;
end
endmodule
Registro de simulación
ncsim> run [0ns] clk=0 rstn=0 out=0xx [5ns] clk=1 rstn=0 out=0x0 [10ns] clk=0 rstn=0 out=0x0 [15ns] clk=1 rstn=0 out=0x0 [20ns] clk=0 rstn=1 out=0x0 [25ns] clk=1 rstn=1 out=0x1 [30ns] clk=0 rstn=1 out=0x1 [35ns] clk=1 rstn=1 out=0x2 [40ns] clk=0 rstn=1 out=0x2 [45ns] clk=1 rstn=1 out=0x3 [50ns] clk=0 rstn=1 out=0x3 [55ns] clk=1 rstn=1 out=0x4 [60ns] clk=0 rstn=1 out=0x4 [65ns] clk=1 rstn=1 out=0x5 [70ns] clk=0 rstn=1 out=0x5 [75ns] clk=1 rstn=1 out=0x6 [80ns] clk=0 rstn=1 out=0x6 [85ns] clk=1 rstn=1 out=0x7 [90ns] clk=0 rstn=1 out=0x7 [95ns] clk=1 rstn=1 out=0x8 [100ns] clk=0 rstn=0 out=0x8 [105ns] clk=1 rstn=0 out=0x0 [110ns] clk=0 rstn=0 out=0x0 [115ns] clk=1 rstn=0 out=0x0 [120ns] clk=0 rstn=0 out=0x0 [125ns] clk=1 rstn=0 out=0x0 [130ns] clk=0 rstn=0 out=0x0 [135ns] clk=1 rstn=0 out=0x0 [140ns] clk=0 rstn=0 out=0x0 [145ns] clk=1 rstn=0 out=0x0 [150ns] clk=0 rstn=1 out=0x0 [155ns] clk=1 rstn=1 out=0x1 [160ns] clk=0 rstn=1 out=0x1 [165ns] clk=1 rstn=1 out=0x2 La simulación finalizó vía $finish(1) en el tiempo 170 NS + 0
Observe que el contador se reinicia a 0 cuando el reset activo-bajo se vuelve 0, y cuando el reset se desactiva alrededor de 150ns, el contador comienza a contar desde la siguiente ocurrencia del flanco positivo de reloj.
Esquema Hardware
Verilog
- Prevención del windup de reinicio PID: estrategias para control de proceso fiable
- Contador Binario de 3 Bits con Temporizador 555 y Flip-Flops 4027
- Contadores Binarios Síncronos: Diseño, Operación Up/Down y Aplicaciones en Codificadores
- Módulo de Contador: Algoritmos Optimizados para Sistemas Modernos
- Contadores Anillo y Johnson: Diseño, Funcionamiento y Aplicaciones Prácticas
- ADC Rampa Digital (Contador): Funcionamiento, Ventajas y Limitaciones
- Recargando, reiniciando y reconfigurando tu estrategia TI para éxito veraniego
- Convergencia IT/OT: Un reinicio cultural para una transformación digital sostenible
- Diseño de Contador Mod-N en Verilog: Módulo Parametrizado y Testbench
- Módulo Contador Gray en Verilog – Generador de Código Gray de 4 Bits
- Counter de collections en Python: conteo eficiente, actualización y operaciones aritméticas