Clock dividers

Counters and their use in frequency dividers

For stable operation, serial circuits need a reliable clock signal to ensure stable time synchronization. To provide a stable frequency source, the clock generator circuit uses a quartz resonator. Driver circuits amplify the signal from the crystal (or oscillator) into a digital signal that is distributed to other devices, such as storage devices, in the digital system.

Most digital circuits require several (or even dozens) of different clock signals to control various subsystems. For example, a system based FPGA can use a 48 kHz clock to generate an audio stream, a 1 kHz clock to run a timer, a 10 MHz clock to run a small processor, and a 12 kHz clock to run a motor controller. It would be too expensive to use separate external oscillator circuits to create so many different clock signals, so systems typically produce the clock signals they need from just one or two main clock inputs. For example, Blackboard uses only one external 100 MHz clock source.

The clock divider circuit produces low-frequency clock signals from the input clock source. The divider counts the input clock cycles and drives the output clock low and then high for a number of input clock cycles. For example, a clock divider could drive the output low while counting five 100 MHz input clock cycles, then drive the output high while counting five more cycles, and so on in an endlessly repeating sequence to produce a 10 MHz clock.

Note that in an FPGA (such as the ZYNQ chip on Blackboard), the clock signals that drive flip-flops can only come from two sources: the main clock input or directly from the flip-flop output. The clock signal cannot come from any logic gate or logic circuit.

A simple halving divider can use a single flip-flop, as shown below. Note that in the Verilog code the output of “clk_div” is cast to type reg in the module port statement. This must be done because “clk_div” is assigned in a procedural assignment statement, and all procedural assignment targets must be of type reg. It is also worth mentioning that the module outputs can be of the type wire or regbut the inputs must be of type wire.

Figure 1. An inverter feedback flip-flop can divide the clock frequency by 2.

Figure 1. An inverter feedback flip-flop can divide the clock frequency by 2.

module dividebytwo (
    input clk, rst,
    output reg clk_div
    );

always @ (posedge(clk), posedge(rst))
begin
    if (rst) clk_div <= 0;
    else clk_div <= !clk_div;
end
endmodule

An n-bit counter can output n divided clock signals, with each subsequent bit oscillating at half the frequency of its less significant neighbor. Each bit divides the input clock signal to a “power of 2”, where the exponent is (bit number + 1) in the counter.

Figure 2. Binary counter bits divide the input clock signal by increasing powers of 2.

Figure 2. Binary counter bits divide the input clock signal by increasing powers of 2.

In the Verilog code below – the “counterout” bus is cast to type regso any or all of the counter bits can be used as clock signals by other circuits.

module counter1(
    input clk, rst,
    output reg [7:0] counterout
    );
    
 always @ (posedge(clk), posedge(rst))
 begin
     if (rst) counterout <= 0;
     else counterout <= counterout + 1;
end
endmodule

A more general counter-based circuit can count any number of clock cycles, toggle the output bit, and then reset itself to create a free-running clock divider. Note that flip-flops in an FPGA (such as the chip on your board) can only use clock pulses coming from the main clock input or directly from the output of another flip-flop. The circuit below divides the main 100 MHz input clock by 100,000 to produce a 1 kHz clock.

Figure 3. General clock divider circuit

Figure 3. General clock divider circuit

The Verilog behavioral block for the clock divider is very similar to the Verilog code for the counter – the difference is one additional “if” statement to check whether the current counter value is equal to the final counter value – if they are, the counter value is set to zero. Note that the final counter value must be equal to half the total clock division constant. This allows the final counter value to toggle T-FFwith the T-FF output driven low for half the desired clock period and then driven high for half the desired clock period. The output of T-FF can be directly used as a clock by another circuit. Note also that the final counter value used is actually (final count – 1) since counting starts at 0.

The code below divides the input clock signal by 50,000, and so the terminal counter constant is set to 25,000 (actually 25,000 – 1). If this circuit were implemented on Blackboard, where the input clock signal is 100 MHz, the resulting output would be 2 kHz.

Try writing Verilog code for the clock divider and then compare your work with the example code here.
module ClkDivider (
    input clk, rst,
    output reg clk_div
    );
	
localparam terminalcount = (25000 - 1);
reg [15:0] count;
wire tc;

assign tc = (count == terminalcount);	// Place a comparator on the counter output

always @ (posedge(clk), posedge(rst))
begin
    if (rst) count <= 0;
    else if (tc) count <= 0;		// Reset counter when terminal count reached
    else count <= count + 1;
end

always @ (posedge(clk), posedge(rst))
begin
    if (rst) clk_div <= 0;
    else if (tc) clk_div = !clk_div;	// T-FF with tc as input signal
end
endmodule

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *