
/* ////////////////////////////////////////////////////////////////////////////
                                     dbn.v
///////////////////////////////////////////////////////////////////////////////
DESCRIPTION:    This is a Verilog model of a divide-by-N counter.  It assumes a
                series of regular pulses on its input line, and produces pulses
                on its output at 1/N times the frequency of the input signal.

                The configurable compile time parameter MAX_COUNT sets the
                value of N.  A second parameter UP_TIME sets the duty cycle of
                the output signal.  That duty cycle is given as a percent by
                the formula (UP_TIME / MAX_COUNT) * 100.

REVISIONS:      22 Sep 07 - RAC - Genesis, following a couple of false starts.
                23 Sep 07 - RAC - Conditionally exported 'counter' for the
                                   benefit of the test bench
//////////////////////////////////////////////////////////////////////////// */

`define MAX_COUNT       10                      // Divide by this number
`define UP_TIME         3                       // Set output duty cycle to 30%
`define COUNTER_WIDTH   4                       // Enough bits to hold a value
                                                //  of MAX_COUNT, but no more
                                                //  than necessary
`ifdef ON_TEST_BENCH
module DivideByN(in, out, counter);
    input in;
    output out;
    output counter;
`else
module DivideByN(in, out);
    input in;
    output out;
`endif

    reg [`COUNTER_WIDTH-1 : 0] counter;         // Count input pulses here
    reg out;                                    // Manage output signal here

    initial begin
        counter <= 0;
        end

    always @(posedge in) begin                  // On every input pulse
        if (counter == `MAX_COUNT - 1) begin    // Time to reset the counter
            counter <= 0;                       // Do so
            end                                 // End 'time to reset counter'
        else begin                              // Not time to reset counter
            counter <= counter + 1;             // Increment it instead
            end                                 // End 'not time to reset'
        out <= counter < `UP_TIME;              // Output is high from counter
        end                                     // End 'on every input pulse'

    endmodule
