// Copyright 2020 Efabless Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0

/* Integer-N clock divider */
`default_nettype none
 
module clock_div #(
    parameter SIZE = 3		// Number of bits for the divider value
) (
    in, out, N, resetb
);
    input in;			// input clock
    input [SIZE-1:0] N;		// the number to be divided by
    input resetb;		// asynchronous reset (sense negative)
    output out;			// divided output clock
 
    wire out_odd;		// output of odd divider
    wire out_even;		// output of even divider
    wire not_zero;		// signal to find divide by 0 case
    wire enable_even;		// enable of even divider
    wire enable_odd;		// enable of odd divider

    reg [SIZE-1:0] syncN;	// N synchronized to output clock
    reg [SIZE-1:0] syncNp;	// N synchronized to output clock
 
    assign not_zero = | syncN[SIZE-1:1];
 
    assign out = (out_odd & syncN[0] & not_zero) | (out_even & !syncN[0]);
    assign enable_odd = syncN[0] & not_zero;
    assign enable_even = !syncN[0];

    // Divider value synchronization (double-synchronized to avoid metastability)
    always @(posedge out or negedge resetb) begin
	if (resetb == 1'b0) begin
	    syncN <= `CLK_DIV;	// Default to divide-by-2 on system reset
	    syncNp <= `CLK_DIV;	// Default to divide-by-2 on system reset
	end else begin
	    syncNp <= N;
	    syncN <= syncNp;
	end
    end
 
    // Even divider
    even even_0(in, out_even, syncN, resetb, not_zero, enable_even);
    // Odd divider
    odd odd_0(in, out_odd, syncN, resetb, enable_odd);
 
endmodule // clock_div
 
/* Odd divider */

module odd #(
    parameter SIZE = 3
) (
    clk, out, N, resetb, enable
);
    input clk;			// slow clock
    output out;			// fast output clock
    input [SIZE-1:0] N;		// division factor
    input resetb;		// synchronous reset
    input enable;		// odd enable
 
    reg [SIZE-1:0] counter;	// these 2 counters are used
    reg [SIZE-1:0] counter2;	// to non-overlapping signals
    reg out_counter;		// positive edge triggered counter
    reg out_counter2;		// negative edge triggered counter
    reg rst_pulse;		// pulse generated when vector N changes
    reg [SIZE-1:0] old_N;	// gets set to old N when N is changed
    wire not_zero;		// if !not_zero, we devide by 1
 
    // xor to generate 50% duty, half-period waves of final output
    assign out = out_counter2 ^ out_counter;

    // positive edge counter/divider
    always @(posedge clk or negedge resetb) begin
	if (resetb == 1'b0) begin
	    counter <= `CLK_DIV;
	    out_counter <= 1;
	end else if (rst_pulse) begin
	    counter <= N;
	    out_counter <= 1;
	end else if (enable) begin
	    if (counter == 1) begin
		counter <= N;
		out_counter <= ~out_counter;
	    end else begin
		counter <= counter - 1'b1;
	    end
	end
    end
 
    reg [SIZE-1:0] initial_begin;	// this is used to offset the negative edge counter
    // wire [SIZE:0] interm_3;		// from the positive edge counter in order to
    // assign interm_3 = {1'b0,N} + 2'b11;	// guarante 50% duty cycle.
    localparam [SIZE:0] interm_3 = {1'b0,`CLK_DIV} + 2'b11;

    // Counter driven by negative edge of clock.

    always @(negedge clk or negedge resetb) begin
	if (resetb == 1'b0) begin
	    // reset the counter at system reset
	    counter2 <= `CLK_DIV;
	    initial_begin <= interm_3[SIZE:1];
	    out_counter2 <= 1;
	end else if (rst_pulse) begin
	    // reset the counter at change of N.
	    counter2 <= N;
	    initial_begin <= interm_3[SIZE:1];
	    out_counter2 <= 1;
	end else if ((initial_begin <= 1) && enable) begin

	    // Do normal logic after odd calibration.
	    // This is the same as the even counter.
	    if (counter2 == 1) begin
		counter2 <= N;
		out_counter2 <= ~out_counter2;
	    end else begin
		counter2 <= counter2 - 1'b1;
	    end
	end else if (enable) begin
	    initial_begin <= initial_begin - 1'b1;
	end
    end
 
    //
    // reset pulse generator:
    //               __    __    __    __    _
    // clk:       __/  \__/  \__/  \__/  \__/
    //            _ __________________________
    // N:         _X__________________________
    //               _____
    // rst_pulse: __/     \___________________
    //
    // This block generates an internal reset for the odd divider in the
    // form of a single pulse signal when the odd divider is enabled.

    always @(posedge clk or negedge resetb) begin
	if (resetb == 1'b0) begin
	    rst_pulse <= 0;
	end else if (enable) begin
	    if (N != old_N) begin
		// pulse when reset changes
		rst_pulse <= 1;
	    end else begin
		rst_pulse <= 0;
	    end
	end
    end
 
    always @(posedge clk) begin
	// always save the old N value to guarante reset from
	// an even-to-odd transition.
	old_N <= N;
    end	
 
endmodule // odd

/* Even divider */

module even #(
    parameter SIZE = 3
) (
    clk, out, N, resetb, not_zero, enable
);
    input clk;		// fast input clock
    output out;		// slower divided clock
    input [SIZE-1:0] N;	// divide by factor 'N'
    input resetb;	// asynchronous reset
    input not_zero;	// if !not_zero divide by 1
    input enable;	// enable the even divider
 
    reg [SIZE-1:0] counter;
    reg out_counter;
    wire [SIZE-1:0] div_2;
 
    // if N=0 just output the clock, otherwise, divide it.
    assign out = (clk & !not_zero) | (out_counter & not_zero);
    assign div_2 = {1'b0, N[SIZE-1:1]};
 
    // simple flip-flop even divider
    always @(posedge clk or negedge resetb) begin
	if (resetb == 1'b0) begin
	    counter <= 1;
	    out_counter <= 1;

	end else if (enable) begin
	    // only use switching power if enabled
	    if (counter == 1) begin
		// divide after counter has reached bottom
		// of interval 'N' which will be value '1'
		counter <= div_2;
		out_counter <= ~out_counter;
	    end else begin
		// decrement the counter and wait
		counter <= counter-1;	// to start next transition.
	    end
	end
    end
 
endmodule //even
`default_nettype wire
