0
\$\begingroup\$

Trying to implement a programmable clock divider in Verilog, with the input divide value able to be set between 1 (clk_out = clk_in) and 2^8 (clk_out = clk_in/256). Here is a working example that performs beautifully in simulation:

module clk_divider (
    input clk_in,
    input [7:0] divider,
    output reg clk_out
);

reg[7:0] counter = 8'd0;

always @(posedge clk_in or negedge clk_in) begin
    
    counter <= counter + 1;

    if (counter >= ((divider * 2) - 1)) begin
        counter <= 0;
    end

    if (divider == 1) begin
        clk_out <= clk_in;
    end else begin
        clk_out <= (counter < divider)?1'b1:1'b0;
    end

end
    
endmodule

...however the astute will surely realize that this is not synthesizable in hardware, specifically the always @(posedge clk_in or negedge clk_in) - attempting to take action on both edges which allows for odd divider values and most importantly my divide by 1 requirement.

Any suggestions for how to implement?

Edit: Final implementation using a mux to pass through clk_in when divider=1. Even-order divides produce 50% duty cycle while odd-order will produce non-50% (off by one half-cycle).

module clk_divider (
    input clk_in,
    input [7:0] divider,
    output wire clk_out
);

reg[7:0] counter = 8'd0;
reg clk_in_div;
wire clk_in_passthru = clk_in;

assign clk_out = (divider == 1)?clk_in_passthru:clk_in_div;

always @(posedge clk_in) begin
    
    counter <= counter + 1;

    if (counter >= (divider - 1)) begin
        counter <= 0;
    end

    clk_in_div <= (counter < (divider / 2))?1'b1:1'b0;

end
    
endmodule
\$\endgroup\$
2
  • \$\begingroup\$ What have you tried? We are not going to just write the code for you. \$\endgroup\$ Sep 2 at 11:12
  • \$\begingroup\$ @ElliotAlderson, I tried exactly what I provided above. \$\endgroup\$
    – Antennae
    Sep 2 at 18:06
0
\$\begingroup\$
  1. The most and simplest way to get rid of "always @(posedge clk_in or negedge clk_in)": MUX the output between the original clock and divided by n clock.
  2. The simplest way: Regenerate a clock at higher rate using the device internal PLL.
  3. Simpler way: Phase shift the clock using logic delay, as many as you want. XOR the original clock and the series of phase shifted clock to regenerate higher frequency clock.
  4. Simple way: Do #3 using external delay-line.
\$\endgroup\$
6
  • \$\begingroup\$ thank you... maybe I am missing something, but seems like your suggestions are for multiplying the clock? I have an external clock coming in that I need to divide down anywhere between freq/1 to freq/256. \$\endgroup\$
    – Antennae
    Sep 2 at 18:35
  • \$\begingroup\$ @Antennae, Yes, the answer is about either 1)multiplying the clock, or 2)multiplexing the clock in order to get freq/1 along with freq/N. \$\endgroup\$
    – jay
    Sep 2 at 19:09
  • \$\begingroup\$ I see. Muxing may be a solution so I can at least get freq/1 output. However without clocking from both edges of the input I can only do even-order divides. May be the best I can do without a whole lot more logic. Thanks for the suggestions. \$\endgroup\$
    – Antennae
    Sep 2 at 19:56
  • \$\begingroup\$ @Antennae , not necessarily get stuck to 2^n or even division, if you willing to give up 50% duty. Does falling edge give that odd division with 50% duty? \$\endgroup\$
    – jay
    Sep 2 at 20:09
  • \$\begingroup\$ 3,4 are highly unrecommended, because OP is targeting FPGAs. \$\endgroup\$
    – Mitu Raj
    Sep 2 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.