In this post, we will be implementing a Clock Divider circuit in Verilog. This is one of the most important circuits in VLSI as we can generate one reference clock, and then divide that clock to obtain a number of other slower clocks.
Design Problem:
Design Problem:
Clock divider is a circuit which can reduce the frequency of a reference clock by any number N.
Example: If I do clock divide by 2, it means frequency of the clock has been reduced by half.
Another way to look at it is that clock divide by 2 means one period of the new clock will fit two periods of the reference clock.
Example: If I do clock divide by 2, it means frequency of the clock has been reduced by half.
Another way to look at it is that clock divide by 2 means one period of the new clock will fit two periods of the reference clock.
General Logic:
Let us deal with the case where N is even.
Clock divide by N means N posedges of the reference clock must fit in one period of the reference clock. This means the new clock should toggle at the (N/2 + 1)th posedge of the reference clock.
Example:
Let's say divide by 4. So 4 posedges of reference clock will be available in one period of the new clk. This means the new clock toggles at the 3rd posedge of the reference clock.
For N odd, we must also toggle the clock at a negedge, we will not deal with this case here as it is not usually preferred in practical designs.
Verilog Logic:
To count the posedges, we need a counter which after coming out of reset, is initialized to 1. It increments after every posedge. At every cnt = N/2 (or N>>1 as shifter is realized in hardware), the new clock has to toggle and the counter must be reset.
Verilog Code:
module clkdiveven ( clk, //reference clk rst, N, //divide by N out_clk //generated clk ); input clk; input rst; input [2:0] N; output out_clk; reg out_clk, next_out_clk; reg [2:0] cnt; reg [2:0] next_cnt; always @ (posedge clk or negedge rst) begin if(!rst) begin out_clk <= 1'b0; cnt <= 1'b0; end else begin out_clk <= next_out_clk; cnt <= next_cnt; end end always @ (*) begin if(cnt==(N>>1)) begin next_out_clk = ~out_clk; next_cnt = 1'b1; end else begin next_out_clk = out_clk; next_cnt = cnt+1; end end endmodule
Testbench:
module clkdiveven_tb; reg clk; reg rst; reg [2:0] N; wire out_clk; clkdiveven c0(clk,rst,N,out_clk); always #5 clk=~clk; initial begin clk=1'b1; rst=1'b0; N=3'b010; #30 rst=1'b1; #70 N=3'b100; #500 $finish; end endmodule
Simulation Result:
Here, when N = 2 the output frequency is reduced by 2 times and when N = 4, the output frequency is reduced by 4 times.
Here is a clock divider design which works for any integral N (odd and even):
A gating logic is used in this design for power saving.
No comments:
Post a Comment