// periodic_timer.sv — auto-reloading down-counter with interrupt pulse module periodic_timer #( parameter int W = 8 ) ( input logic clk, input logic rst, // synchronous, active-high input logic load, // start / restart with a new period input logic [W-1:0] period, // spec: 0 = off, otherwise must be >= 2 input logic stop, // pause while high output logic [W-1:0] count, // cycles left in the current period output logic [W-1:0] period_q, // stored period output logic running, output logic irq // one-cycle pulse at the end of each period ); always_ff @(posedge clk) begin if (rst) begin count <= '0; period_q <= '0; running <= 1'b0; irq <= 1'b0; end else begin irq <= 1'b0; if (load) begin count <= period; period_q <= period; running <= (period != '0); end else if (running && !stop) begin if (count == W'(1)) begin count <= period_q; // auto-reload irq <= 1'b1; end else begin count <= count - W'(1); end end end end endmodule