module sck_clk_divider
(
    input       clk,
    input       rst_n,
    output      sck,
    output      sck_edge
);
    localparam  S_DOWN = 0,
                S_EDGE = 1,
                S_UP   = 2;

    localparam  DOWN_SIZE = 7,
                UP_SIZE = DOWN_SIZE - 1; // because 1 cycle of S_EDGE;

    // State hold registers
    wire [1:0] State;
    reg  [1:0] Next;
    register #(.SIZE(2)) r_state(clk, rst_n, Next, State);

    wire [2:0] cnt;
    reg  [2:0] cntNext;
    register #(.SIZE(3)) r_cnt(clk, rst_n, cntNext, cnt);

    // Next state determining
    always @(*) begin
        Next = State;
        case(State)
            S_DOWN  : if(cnt == DOWN_SIZE) Next = S_EDGE;
            S_EDGE  : Next = S_UP;
            S_UP    : if(cnt == UP_SIZE) Next = S_DOWN;
        endcase
    end

    always @(*) begin
        cntNext = cnt + 1;
        case(State)
            S_DOWN  : if (cnt == DOWN_SIZE) cntNext = 0;
            S_EDGE  : cntNext = 0;
            S_UP    : if (cnt == UP_SIZE) cntNext = 0;
        endcase
    end

    // output
    assign sck_edge = (State == S_EDGE);

    // buffered output
    wire sckNext = (Next != S_DOWN);
    register #(.SIZE(1)) r_sck(clk, rst_n, sckNext, sck);

endmodule