Verilog Examples - Clock Divide by 4.5

It is possible to generate a clock divided by 4.5 or for that matter any number like N+1/2. It involves some math. In this example we will use a ring counter that counts on the positive edge of clock.

We then use some counters at negative edges. The counters that we need is dictated by Math.

One advantage of the method we present below is that it does not create multilexers and hence is free from glithes. It however does not have 50% duty cycle.

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 4.5 times the frequency of the input clock. It has a negative reset input.

Solution -

This is the main code clock.v

 module clk_divn (clk,reset, clk_out); input clk;input reset;output clk_out; reg [8:0] count; reg ps_count1,ps_count5,ps_count6 ;  /* Counter reset value : 9�b000000001 *//* count is a ring counter */ always @( posedge clk or negedge reset)if (!reset)count[8:0] <= 9'b000000001;elsebegincount <= count << 1;count <= count;endalways @(negedge clk or negedge reset)if (!reset)beginps_count1 <= 1'b0;ps_count5 <= 1'b0;ps_count6 <= 1'b0;endelsebeginps_count1 <= count;ps_count5 <= count;ps_count6 <= count;end // Use this Math to generate an this odd clock divider. assign clk_out = (ps_count5 | ps_count6| count)|(count | count | ps_count1);  endmodule

Here is the test bench clocktb.v

 `timescale 1ns/100psmodule clkdiv3_tb; reg clk,reset; wire clk_out;  clk_divn t1(clk,reset,clk_out); initial clk= 1'b0; always #5 clk=~clk; initial begin #6 reset=1'b1; #6 reset=1'b0; #6 reset=1'b1; #500 \$finish; end  initial \$monitor("clk=%b,reset=%b,clk_out=%b",clk,reset,clk_out);  initial begin \$dumpfile("clkdiv45_tb.vcd"); \$dumpvars(0,clkdiv3_tb); end endmodule

Here is the result of the simulation count of the number of positive and negative pulses. for N=7. Explanation 1. A ring counter is implemmented using

 begin count <= count << 1; count <= count; end

If you look at the counters in the code, you need to check the time periods of the OR of the followin two sets
count | count | ps_count1
and
ps_count5 | ps_count6| count);