2
\$\begingroup\$

I am an electronics student and learning Verilog. I had an assignment to build an clock divider for arbitrary frequency. I have made a module that works,

module N_clock(clk_in, freq_main, freq_N, clk_out);

input clk_in;
input [31:0] freq_main, freq_N;
output clk_out;
wire reg [31:0] d;
reg [31:0] counter = 32'd0;

assign d = freq_main / freq_N;
always@(posedge clk_in)
begin
if (counter<=d)
    counter = counter + 32'd1;
else
    counter<=32'd0;
end

assign clk_out = counter<(d/2) ? 1'b1 : 1'b0;
endmodule

My question is, is it possible to implement this module in an FPGA. I'm concerned mostly because of the division I did in line 9. I would like to know if there's any method of implementing physically or any other workaround.

PS: This question is not related to my assignment. The above module is enough for that. However, I am curious.

\$\endgroup\$
0

2 Answers 2

3
\$\begingroup\$
assign d = freq_main / freq_N

The above simple statement is asking too much effort from a synthesiser. Since both divident and divisor are of 32-bits and are run-time configurable, you are basically asking the synthesiser to implement a combinational 32-bit divider core, which I really doubt how many synthesisers will be able to infer. If at all it is supported, it will be a poor implementation in terms of accuracy (integer rounding); and timing, since divisions are complex operations.

If the divisor is a power of 2, and if it is deduced at the compile-time, the division operation will be supported by almost every synthesiser. For instance, in Xilinx Vivado it is supported:

enter image description here

If you want to implement a divided clock to clock another logic:

  1. I suggest you to not use RTL, as the divided clock gets routed through the fabric with poor skew and slew. So, use a dedicated clock synthesiser IP like PLL/MMCM, and make use of dedicated global clock routing resources . However you will have two synchronous clock domains here.
  2. Generate a clock-enable pulse at the required frequency, using the input clock. And use this clock-enable inside the logic.The logic here runs at the same input clock. In this way, every logic functions in a single clock domain. Refer to this solution.
\$\endgroup\$
3
  • \$\begingroup\$ Thanks for the insight. I didn't really understand much as I'm new to this whole thing. My assignment was to take 50MHz clock as input and output an arbitrarily decided clock frequency in [1Hz,1MHz]. So, now I know that, that division is really too much for a synthesizer. Is there any workaround? I could do the division outside and just directly input the counter. But I'd like to know if there is any simpler way to do the division in the main module. \$\endgroup\$ May 10, 2021 at 12:55
  • \$\begingroup\$ If the assignment asks you to do in RTL, then you can assume input and output clock frequencies are known to the user, and user inputs only the clock division factor to your module. There will be only 2 inputs: clock in and division factor. One output: clock out. Suppose input division factor is 4, the module has to count from: 0 to (4/2 - 1), and generate a clock. \$\endgroup\$
    – Mitu Raj
    May 10, 2021 at 13:21
  • \$\begingroup\$ learn.digilentinc.com/Documents/262 \$\endgroup\$
    – Mitu Raj
    May 10, 2021 at 13:24
3
\$\begingroup\$

That division operation works fine fine. It just treats everything as a truncated integer. However, be aware The clock is not a regular signal that runs through the logic fabric. Clock signals on FPGAs are distributed through one of the clock distribution networks on the FPGA in order to minimizes skew. There are only a limited number of these networks on the FPGA. This is why you use the hardware PLL or divider on the FPGA. The "posedge" keyword tells the software that the signal used with it should be routed through the clock distribution network and not treated as a regular signal.

Running a clock through logic is bad practice and unreliable. Are you sure you don't need a clock enable instead that triggers every n clock cycles?

You only truly need a slower clock if you have a logic sequence so long that it cannot finish within a shorter clock cycle, and if this is the case you should use the hardware clock divider and distribution. Otherwise, you can just run a fast clock and just execute every n clock cycles.

A clock enable is a pulse that lasts for only a single clock cycle and is used to trigger other blocks to run. This allows the other blocks to be clocked off the hardware clock but not run every single clock cycle. Very important since many processes muck up the data flow if they are running every clock cycle but the system is not ready to feed them new inputs or receive their outputs.

A clock enable is very similar to what you have right now except that once the pulse goes high, you being it low again the very next clock cycle.

If that is what your assignment wants, fine. But if you actually try to divide a clock like that in a project and use it to clock things, it is going to bite you in the ass.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks. My assignment is just simulating a module to output an arbitrary clock. So, the above module works. But I was curious if the division statement is actually implementable in FPGA. \$\endgroup\$ May 10, 2021 at 12:49

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.