Verilog Examples - Clock Divide by even number 2N

A clock Divide by 2N circuit has a clock as an input and it divides the clock input by 2N. So for example, if the frequency of the clock input is 50 MHz, and N = 5, the frequency of the output will be 5 MHz. In other words the time period of the outout clock will be 2N times time perioud of the clock input.

To generate a clock frequency ny even number you only need to work on the rising edge of clock and hence the circuit is simplified and potentially free from the glitches that a clock divided by an odd number works.

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 that is 1/2N frequency of the input clock. 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

 module clk_div #( parameter WIDTH = 3, // Width of the register requiredparameter N = 6// We will divide by 12 for example in this case)(clk,reset, clk_out); input clk;input reset;output clk_out; reg [WIDTH-1:0] r_reg;wire [WIDTH-1:0] r_nxt;reg clk_track; always @(posedge clk or posedge reset) begin if (reset) begin r_reg <= 0; clk_track <= 1'b0; end  else if (r_nxt == N) begin r_reg <= 0; clk_track <= ~clk_track; end  else r_reg <= r_nxt;end  assign r_nxt = r_reg+1; assign clk_out = clk_track;endmodule

Here is the test bench clocktb.v

 module clkdiv2n_tb; reg clk,reset; wire clk_out;  clk_div t1(clk,reset,clk_out); initial clk= 1'b0; always #5 clk=~clk; initial begin #5 reset=1'b1; #10 reset=1'b0; #500 \$finish; end  initial \$monitor("clk=%b,reset=%b,clk_out=%b",clk,reset,clk_out);  initial begin \$dumpfile("clkdiv2n_tb.vcd"); \$dumpvars(0,clkdiv2n_tb); end endmodule

The waveform generated by this code is here Explanation

We have used two parameters - one is N which defines half the value of the divider. Another parameter WIDTH helps define the register width. The register width depends upon N. It is the minimum number of widths needed to count N. For example if N is 8 ( binary 4'b1000), WIDTH will be 4. If N is 21, WIDTH will be.

 module clk_div #( parameter WIDTH = 3, // Width of the register required parameter N = 6// We will divide by 12 for example in this case )

We have triggered the always block at positive edge of clock and count up to N and then invert the output clock.

 if (r_nxt == N) begin r_reg <= 0; clk_track <= ~clk_track; end

In the testbench you may try to use a different parameter that will create a different divider when calling module. ( See the exercise below). For example following will divide by 24.

 clk_div #(4, 12) t1(clk,reset,clk_out);

The reset of the code should be easy to understand

Exercize

1. Create a top module that has clk and reset as input and has two outputs call them clk_out1 and clk_out2. The module creates two instances of the clock module clk_div that we created above. One will divide the clock by 10 and other will divide it by 20. Create test bench to verify it.