Verilog Examples - Clock Divide by n odd


We will now extend the clock Divide by 3 code to division by any odd numner. As earlier, we again have to keep a count of the number of the rising and falling edges. Then we use a clever mathematics to drive clock that is divided by an odd number.



Problem - Write verilog code that has a clock and a reset as input. It has an output that can be called clk_out. The clk_out is also a clock that has a frequency 1/N times the frequency of the input clock, where N is an odd number. It has synchronous reset and if there if the reset is 1, the outclock resets to 0. Write test bench to verify it.

Solution -

This is the main code clock.v



  1. module clk_divn #(
  2. parameter WIDTH = 3,
  3. parameter N = 5)
  4.  
  5. (clk,reset, clk_out);
  6.  
  7. input clk;
  8. input reset;
  9. output clk_out;
  10.  
  11. reg [WIDTH-1:0] pos_count, neg_count;
  12. wire [WIDTH-1:0] r_nxt;
  13.  
  14. always @(posedge clk)
  15. if (reset)
  16. pos_count <=0;
  17. else if (pos_count ==N-1) pos_count <= 0;
  18. else pos_count<= pos_count +1;
  19.  
  20. always @(negedge clk)
  21. if (reset)
  22. neg_count <=0;
  23. else if (neg_count ==N-1) neg_count <= 0;
  24. else neg_count<= neg_count +1;
  25.  
  26. assign clk_out = ((pos_count > (N>>1)) | (neg_count > (N>>1)));
  27. endmodule
  28.  




Here is the test bench clocktb.v

  1. `timescale 1ns/100ps
  2. module clkdiv3_tb;
  3. reg clk,reset;
  4. wire clk_out;
  5.  
  6. clk_divn t1(clk,reset,clk_out);
  7. initial
  8. clk= 1'b0;
  9. always
  10. #5 clk=~clk;
  11. initial
  12. begin
  13. #5 reset=1'b1;
  14. #10 reset=1'b0;
  15. #500 $finish;
  16. end
  17.  
  18. initial
  19. $monitor("clk=%b,reset=%b,clk_out=%b",clk,reset,clk_out);
  20.  
  21. initial
  22. begin
  23. $dumpfile("clkdiv3_tb.vcd");
  24. $dumpvars(0,clkdiv3_tb);
  25. end
  26. endmodule
  27.  




Explanation

1. We count the number of the positive edges and the negative edges.

2. Notice the math involved.

assign clk_out = ((pos_count > (N>>1)) | (neg_count > (N>>1)));


N>>1 needs some explanation. If N were an even number N>>1 is simply a division by 2.

But here N is an odd number. Consider for example N is 11 or 5'b10011. We know that when we do right shift, the right most bit is lost - which is equivalent to N getting converted to N-1. And then the right shift divides the number by 2. So N>>1, when, N is off mean N becomes (N-1)/2.

So, when N =11, N >> 1 make it 5. If = 5 or 3'b101, then the N>>1 makes it 3'b010 ( The right most digits is lost) or 2.

3. To understand how the math works out consider the two counters in the figure below that keeps count of the number of positive and negative pulses. for N=7.



Now look at the time periods when the positive count satisfies the condition (pos_count > (N>>1)) , in this case pos_count > 3.



And looks the time periods and negative count is > (N>>1), highlighted by light brown.



Finally we combine the two conditions to get the positive pulse.



4. The trick is to look at the waveforms for the counters for an example ( set N to any fixed number) and find the right math to fit it. Once the math works, generalize it for N.