Frequency or clock dividers are among the most common circuits used in digital systems. The timing diagram in figure 1 (originally used in this article) describes a circuit that divides the input frequency by 12. The circuit simply counts the rising edges of 6 input clock cycles(clk) and then toggles the output clock signal from 1 to 0 or vice-versa.
Fig 1. Timing diagram of frequency divider by 12
This works great when your input frequency is divided by an even number. But things get a little more complicated when we try to divide the frequency by an odd number, since we can't simply divide the number of input clock cycles by 2. If we observe the timing diagram describing a frequency divider by 5 in figure 2, the output clock toggles in the middle of the 3rd input clock cycle and before we are able to complete our count.
Fig 2. Timing diagram of frequency divider by 5
2. Circuit Description
To divide a frequency by an odd number we will need to create a few more signals to use both sequential and combinational logic.
The easiest way of understanding the circuit is by observing the timing diagram below (figure 3):
- Assume we want to divide our frequency by N. For this example, N=5.
- The signal clk_in is our input clock and each cycle is 2ns long, giving us a frequency of 500MHz.
- The signal bus Count is our counter and will reset to 0 after counting (N-1) clk_in cycles. For our example, our counter will count up to 4 (b'0100) since 0 also counts as a number.
- Signal A is set to high (1) whenever the counter is 1 (Count=0001). Otherwise, it stays low (0).
- Signal B is set to high (1) whenever the counter is (N+1)/2. For our example, we used Count=3 (b'0011) since (5+1)/2=3.
- Signal Tff_A is a T flip flop triggered by the falling edge of signal A. Whenever, A goes from 1 to 0, Tff_A is toggled.
- Signal Tff_B is a T flip flop triggered by the falling edge of clk_in only if B is high (1). Whenever B is high, Tff_B will be toggled at the falling edge of the input clock.
- The signal clk_out is our output clock. To produce this signal, we use an XOR gate between the signals Tff_A and Tff_B. The output of an XOR gate is high (1) when the two input signals are different (01, 10) and low (0) if the signals are the same (00, 11). Each cycle of the output clock takes 10ns, with a frequency of 50MHz.
Fig 3. Timing diagram showing all signals required for frequency divider by 5
A more technical explanation on how to divide clocks by odd numbers can be found in the application note AND8001-D published by ON Semiconductors.
3. Verilog Implementation
The Verilog code for a Frequency Divider by 5 can also be downloaded from my Github repository at https://github.com/sphanlung/FPGA/blob/master/clk_div_odd.v
module clk_div_odd(
input clk_in,
output clk_out
);
reg [3:0] count = 4'b0; //4-bit counter
reg A1 = 0;
reg B1 = 0;
reg Tff_A = 0;
reg Tff_B = 0;
wire clock_out;
wire wTff_A;
wire wTff_B;
//Connects registers to wires for combinational logic
assign wTff_A = Tff_A;
assign wTff_B = Tff_B;
assign clk_out = wTff_B ^ wTff_A; //XOR gate
//Counter for division by N
always@(posedge clk_in)
begin
if(count == 4'b0100) //Count to N-1.
begin // Example: Use 4 to divide by 5
count <= 4'b0000;
end
else
begin
count <= count + 1;
end
end
//Set A to high for one clock cycle when counter is 0
always@(posedge clk_in)
begin
if(count == 4'b0000)
A1 <= 1;
else
A1 <= 0;
end
//Sets B to high for one clock cycle when counter is (N+1)/2
always@(posedge clk_in)
begin
if(count == 4'b0011) //Use (N+1)/2
B1 <= 1; //Ex: (5+1)/2 = 3
else
B1 <= 0;
end
//T flip flop toggles
always@(negedge A1) // Toggle signal Tff_A
begin //whenever A1 goes from 1 to 0
Tff_A <= ~Tff_A;
end
always@(negedge clk_in)
begin
if(B1) // Toggle signal Tff_B whenever
begin //B1 is 1
Tff_B <= ~Tff_B;
end
end
endmodule
Fig 4. RTL schematic generated by Xilinx ISE
No comments:
Post a Comment