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
asked Sep 2, 2021 at 2:59
\$\endgroup\$
2
  • \$\begingroup\$ What have you tried? We are not going to just write the code for you. \$\endgroup\$ Commented Sep 2, 2021 at 11:12
  • \$\begingroup\$ @ElliotAlderson, I tried exactly what I provided above. \$\endgroup\$ Commented Sep 2, 2021 at 18:06

1 Answer 1

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.
answered Sep 2, 2021 at 17:14
\$\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\$ Commented Sep 2, 2021 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\$ Commented Sep 2, 2021 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\$ Commented Sep 2, 2021 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\$ Commented Sep 2, 2021 at 20:09
  • \$\begingroup\$ 3,4 are highly unrecommended, because OP is targeting FPGAs. \$\endgroup\$ Commented Sep 2, 2021 at 20:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.