How to Write a verilog code for Clock Divider

Hi there my name is Praful! Today, I’m excited to share with you a glimpse into a project I’ve been working on—a clock divider module written in Verilog. If you’re not familiar with digital design or Verilog, you might wonder what exactly that means. Well, I’m here to explain it in a way that’s easy to understand, highlighting why it’s so fascinating and important.

The Essence of Clock Signals in Digital Systems

In the digital world, a clock signal acts like the pulse for electronic systems, coordinating the operations of its components. But sometimes, different parts of a system need to operate at slower speeds than the main clock signal. That’s where a clock divider comes in—it takes the main clock signal and produces slower versions of it.

A clock signal serves as the heart of synchronous systems, orchestrating the timing of all operations. However, different parts of a system often require clock signals at lower frequencies than the main clock. This necessitates the use of clock dividers, which generate multiple clock signals, each with a frequency that is a fraction of the input clock signal.

Here is the Step by step guide through the code explaining each and every step

Let’s dive into the heart of the clock divider module I’ve developed. The module takes one input, the main clock signal, and generates six outputs, each a divided-down version of the input clock. The outputs are aptly named f2, f4, f8, f16, f32, and f64, indicating how much slower they are compared to the input clock.

Here’s the core part of the module:

Verilog
module clock_divider(input clk, output reg f2, f4, f8, f16, f32, f64);

This line defines our module with its input and outputs. Inside, we use a special counter that keeps track of the input clock’s cycles. As this counter increases with each clock pulse, it controls when each output toggles, creating the divided clock signals. It’s like a metronome that can be set to tick at different speeds based on how we program it.

Verilog
reg [5:0] count = 0;

A 6-bit register count is defined to keep track of the clock cycles. It’s initialized to 0 and serves as the backbone for dividing the clock by toggling its bits.

Verilog
always @(posedge clk) begin

This block executes on every positive edge of the input clock, ensuring that the division is synchronous with the clock’s rising edge, a critical aspect for maintaining temporal accuracy in digital circuits.

Verilog
count <= count + 1;
f2 <= count[0];
f4 <= count[1];
f8 <= count[2];
f16 <= count[3];
f32 <= count[4];
f64 <= count[5];

Within the always block, the count is incremented by one on each clock’s positive edge. The least significant bit (LSB) of count toggles every clock cycle, effectively creating a clock signal with half the frequency of the input clock (f2). Similarly, the subsequent bits generate f4, f8, f16, f32, and f64, each dividing the clock frequency by increasing powers of two.

Verilog
    end
endmodule

Finally we are ending the initial block and the module

Below is the Complete code for clock divider Design under Test

Verilog
// Clock Divider Code by Praful Kharade
// Logicflick.com

module clock_divider(input clk,
                    output reg f2, f4, f8, f16, f32, f64);
  reg [5:0] count = 0; 
  
  always @(posedge clk) begin
  
    
    count <= count + 1;
    f2 <= count[0];
    f4 <= count[1];
    f8 <= count[2];
    f16 <= count[3];
    f32 <= count[4];
    f64 <= count[5];
  end
endmodule

If you want to Directly Run the code on EDA Playground you can do that by clicking the button below

Test bench

Imagine you’ve just finished designing a sophisticated digital clock that can divide a single clock signal into multiple, slower signals. How do you make sure it works? This is where a testbench comes into play. It’s a virtual environment where we can simulate our design, feeding it inputs and examining the outputs without ever needing to build it physically. Think of it as a digital proving ground for your designs.

Module Declaration: The testbench itself is declared as a module named tb_freq. In Verilog, both designs and testbenches are modules, but the latter is used purely for simulation purposes.

Verilog
module tb_freq;

Signal Declaration: Within this module, clk is declared as a reg type because we need to control it manually to simulate an input clock. The divided clock outputs (f2, f4, f8, f16, f32) are declared as wire types since they will be driven by the clock divider module we are testing.

Verilog
reg clk;
wire f2, f4, f8, f16, f32;

Clock Divider Instance: This part of the code connects our testbench to the clock divider module (clock_divider) we aim to test. We map the clk signal to the clock input of the divider and the f2 to f32 signals to its outputs, effectively creating a test scenario for our module.

Verilog
clock_divider instance1(.clk(clk), .f2(f2), .f4(f4), .f8(f8), .f16(f16), .f32(f32), .f64(f64));

Clock Simulation: The always block is where we simulate the ticking of the clock. By toggling clk every 5 simulation time units, we mimic the rising and falling edges of a real clock signal.

Verilog
always #5 clk = ~clk;

Initial Block: The initial block sets the initial conditions of the simulation and defines its duration. We start by setting clk to 0, run the simulation for 400 time units, then end the simulation. This block also includes commands to generate a waveform (dump.vcd) that we can analyze to visually verify our clock divider’s behavior.

Verilog
initial begin
  $dumpfile("dump.vcd");
  $dumpvars(1);
  clk = 0;
  #400;
  $finish;
end

Here is the complete Test bench code for Clock Divider

Verilog
// Code by Praful Kharade
// Logicflick.com

module tb_freq;
  reg clk;
  wire f2, f4, f8, f16, f32;

  clock_divider instance1(.clk(clk),
                          .f2(f2),
                          .f4(f4),
                          .f8(f8),
                          .f16(f16),
                          .f32(f32),
                          .f64(f64)
                       
                        
                         );
always #5 clk = ~clk;
                    	
  initial 
    begin
      $dumpfile("dump.vcd");
      $dumpvars(1);
      
      clk =0;
      #400;
      $finish;
    end
endmodule

Output waveform of Clock Divider circuit

The Significance of the Testbench

Why go through all this trouble? Well, in the absence of a testbench, we’d have no straightforward way to verify the functionality of our design without physically building it—a process that’s both time-consuming and potentially costly. With a testbench, we can catch errors early, iterate quickly, and gain confidence in our design before it ever makes its way into a physical device.

To sum up

Walking through this testbench has hopefully demystified some aspects of digital verification and illustrated the critical role it plays in the design process. Whether you’re a seasoned engineer or new to digital design, understanding how to effectively use testbenches is a crucial skill in the toolkit of anyone working with digital circuits.

Leave a Reply

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