module timer #(
  parameter MAX_VALUE = 16384 // ticks
) (
  input wire clk,
  input wire [`REG_TIMER_WIDTH-1:0] init,
  input wire start,
  output reg overflow
);
  reg [`REG_TIMER_WIDTH-1:0] counter = 0;
  reg [`CLOG2(MAX_VALUE)-1:0] sub_counter = 0;

  /*
   * Detect when start is initially set, use it to reset the timer value back
   * to the initial value. Also if start is not set clock will not run.
   */
  opl_edge_detector #(
    .EDGE_LEVEL(1),
    .CLK_DLY(1)
  ) start_timer_edge_detect (
    .clk(clk),
    .clk_en(1'b1),
    .in(start),
    .edge_detected(start_pulse)
  );

  /*
   * Timer gets set to init upon overflow
   */
  always @(posedge clk) begin
    overflow <= 0;

    if (start_pulse) begin
      counter <= init;
      sub_counter <= MAX_VALUE - 1;
    end else if (start) begin
      sub_counter <= sub_counter - 1;
      if (!sub_counter) begin
        sub_counter <= MAX_VALUE - 1;
        counter <= counter + 1;
        if (&counter) begin
          overflow <= 1;
          counter <= init;
        end
      end
    end
  end
endmodule