32 / 37 · Práctica
Práctica integrada: pulsos periódicos y acumulador habilitado
Especifica transferencias con valores anteriores y compara pausas, pulsos consecutivos y reinicio simultáneo.
Las lecciones se pueden leer gratis. Inscríbete para guardar el progreso.
Define el contrato antes de conectar
Acepta sample de cuatro bits sin signo en cada ascendente con enable=1. Cada muestra aceptada número N produce pulse registrado. El acumulador consume ese evento y su muestra guardada en el siguiente ascendente, aunque enable sea entonces 0. total de ocho bits vuelve módulo 256. Reset síncrono limpia ambas etapas y descarta cualquier muestra pendiente. El retraso de un flanco es parte del contrato: se leen pulse y saved_sample anteriores, no los valores no bloqueantes recién producidos en ese mismo flanco. Guarda modulo_tick.sv y este periodic_accumulator.sv; N es positivo.
module periodic_accumulator #(parameter integer N = 3) (
input logic clk, rst, enable,
input logic [3:0] sample,
output logic pulse,
output logic [7:0] total
);
localparam integer CW = (N <= 1) ? 1 : $clog2(N);
wire [CW-1:0] count;
logic [3:0] saved_sample;
modulo_tick #(.N(N)) tick_u (
.clk(clk), .rst(rst), .enable(enable),
.count(count), .pulse(pulse)
);
always_ff @(posedge clk) begin
if (rst) saved_sample <= 4'b0;
else if (enable) saved_sample <= sample;
end
always_ff @(posedge clk) begin
if (rst) total <= 8'b0;
else if (pulse) total <= total + {4'b0, saved_sample};
end
endmoduleSigue datos y evento juntos
N=3; entradas anteriores al flanco, salidas posteriores.
| Flanco | rst | enable | sample | pulse después | total después |
|---|---|---|---|---|---|
| E0 | 1 | 1 | 9 | 0 | 0 |
| E1 | 0 | 1 | 2 | 0 | 0 |
| E2 | 0 | 1 | 4 | 0 | 0 |
| E3 | 0 | 1 | 7 | 1 | 0 |
| E4 | 0 | 0 | 9 | 0 | 7 |
| E5 | 0 | 1 | 1 | 0 | 7 |
| E6 | 0 | 1 | 3 | 0 | 7 |
| E7 | 0 | 1 | 5 | 1 | 7 |
| E8 | 1 | 1 | 15 | 0 | 0 |
E4 suma 7, no la nueva muestra 9. enable controla nuevas aceptaciones, no cancela pendientes. E8 descarta 5 pendiente y borra total. Condicionar consumo a enable && pulse perdería E4.
Referencia en la frontera del sistema
Mantén conteo de aceptadas, un valor pendiente opcional y total entero. En cada flanco sin reset consume primero el pendiente anterior módulo 256; después examina enable/sample actuales para crear un nuevo pendiente cada N aceptadas. Reset limpia todo. No dependas de tick_u.count ni saved_sample. Usa estímulo descendente y comparación posterior; verifica cada pulse/total, mantenimiento sin evento y eliminación tras consumir.
Cubre fallos de integración
- N=1: cada muestra aceptada se consume una vez al flanco siguiente, incluso con pulsos consecutivos.
- N=3: inserta pausas antes y después del terminal; cuenta aceptaciones, no relojes.
- Cambia sample externo durante consumo deshabilitado: usa la muestra guardada.
- Reinicia con evento pendiente: se descartan evento y total.
- Cruza 255 para comprobar módulo 256.
Sustituye saved_sample por sample: E4 debe fallar. Bloquea consumo con enable y comprueba otro fallo. Restaura la implementación antes del PASS. Esto verifica un contrato funcional de un reloj y anchura finita, no CDC, cierre temporal físico ni una ejecución gratuita real de DDS.