Verilog Examples - Clock Divide by 2


A clock Divider has a clock as an input and it divides the clock input by two. So for example if the frequency of the clock input is 50 MHz, the frequency of the output will be 25 MHz. In other words the time period of the outout clock will be twice the time perioud of the clock input.

The figure shows the example of a clock divider.



Problem - Write verilog code that has a clock and a reset as input. It has an output that can be called out_clk. The out_clk is also a clock that has a frequency half the frequency of the input clock. It has synchronous reset and if there if the reset is 0, the outclock resets to 0. Write test bench to verify it.

Solution -

This is the main code clock.v



  1. module frequency_divider_by2 ( clk ,rst,out_clk );
  2. output reg out_clk;
  3. input clk ;
  4. input rst;
  5. always @(posedge clk)
  6. begin
  7. if (~rst)
  8. out_clk <= 1'b0;
  9. else
  10. out_clk <= ~out_clk;
  11. end
  12. endmodule
  13.  
  14.  




Here is the test bench clocktb.v

  1. `timescale 1ns/100ps
  2. module frequencydiv;
  3. output reg clk;
  4. output reg rst;
  5. input wire out_clk;
  6. frequency_divider_by2 freq1(clk,rst,out_clk);
  7. initial
  8. clk = 1'b0;
  9. always
  10. #10 clk = ~clk;
  11. initial
  12. begin
  13. $monitor($time,"clk = %b,rst = %b,out_clk = %b",clk,rst,out_clk);
  14. rst =0;
  15. #20 rst =1;
  16. #100 $finish;
  17. end
  18. initial
  19. begin
  20. $dumpfile ("frequencydiv.vcd");
  21. $dumpvars (0,frequencydiv);
  22. end
  23. endmodule
  24.  
  25.  


And the result of the simulation.

	
	                   0 clk = 0,rst = 0,out_clk = x
                  10 clk = 1,rst = 0,out_clk = 0
                  20 clk = 0,rst = 1,out_clk = 0
                  30 clk = 1,rst = 1,out_clk = 1
                  40 clk = 0,rst = 1,out_clk = 1
                  50 clk = 1,rst = 1,out_clk = 0
                  60 clk = 0,rst = 1,out_clk = 0
                  70 clk = 1,rst = 1,out_clk = 1
                  80 clk = 0,rst = 1,out_clk = 1
                  90 clk = 1,rst = 1,out_clk = 0
                 100 clk = 0,rst = 1,out_clk = 0
                 110 clk = 1,rst = 1,out_clk = 1
                 120 clk = 0,rst = 1,out_clk = 1


The waveform is here



Explanation

The code is simple to understand. All you need to do is to set the output clock to 0 at the time of reset.

always @(posedge clk)
begin
if (~rst)
     out_clk <= 1'b0;


In this example the reset was required to be synchronous. If we needed an asynchronous reset, we could have done it as

always @(posedge clk or negedge rst)
begin
if (~rst)
     out_clk <= 1'b0;


The code is simple as all we need to do is invert the output clock at each of its rising edge.

In the next problem / example how to divide this clock by any number n.