----------------------------------------------------------------------------------------
Description:- Verilog Clock Generator
Developer :- Shah Henisha
Date:- 24/02/2025
email :- [Link]@[Link]
Version :- 1.0
---------------------------------------------------------------------------------------
**************************************************************************************************
Question:1
**************************************************************************************************
Q1) Generate variable clock frequency like 1 Mhz , 100 Mhz , 10
Khz , 20 Khz from 500 Mhz.
******************************************************************************************
Code:
******************************************************************************************
module clock_divider (
input wire clk, // 500 MHz clock input
input wire rst, // Reset input
output reg clk_1M, // 1 MHz clock output
output reg clk_100M, // 100 MHz clock output
output reg clk_10K, // 10 KHz clock output
output reg clk_20K // 20 KHz clock output
);
integer count_1M = 0;
integer count_100M = 0;
integer count_10K = 0;
integer count_20K = 0;
always @(posedge clk or posedge rst) begin
if (rst) begin
count_1M <= 0;
count_100M <= 0;
count_10K <= 0;
count_20K <= 0;
clk_1M <= 0;
clk_100M <= 0;
clk_10K <= 0;
clk_20K <= 0;
end else begin
// 1 MHz clock (divide by 500)
count_1M <= count_1M + 1;
if (count_1M >= 250) begin
clk_1M <= ~clk_1M;
count_1M <= 0;
end
// 100 MHz clock (divide by 5)
count_100M <= count_100M + 1;
if (count_100M >= 2) begin
1
clk_100M <= ~clk_100M;
count_100M <= 0;
end
// 10 KHz clock (divide by 50000)
count_10K <= count_10K + 1;
if (count_10K >= 25000) begin
clk_10K <= ~clk_10K;
count_10K <= 0;
end
// 20 KHz clock (divide by 25000)
count_20K <= count_20K + 1;
if (count_20K >= 12500) begin
clk_20K <= ~clk_20K;
count_20K <= 0;
end
end
end
endmodule
Testbench:
`timescale 1ns/1ps
module tb_clock_divider;
reg clk;
reg rst;
wire clk_1M;
wire clk_100M;
wire clk_10K;
wire clk_20K;
// Instantiate the clock divider module
clock_divider uut (
.clk(clk),
.rst(rst),
.clk_1M(clk_1M),
.clk_100M(clk_100M),
.clk_10K(clk_10K),
.clk_20K(clk_20K)
);
// Generate 500 MHz clock (Period = 2 ns)
always #1 clk = ~clk;
initial begin
$dumpfile("clock_divider.vcd");
$dumpvars(0, tb_clock_divider);
// Initialize signals
clk = 0;
rst = 1;
#10 rst = 0; // Release reset after some time
// Run simulation for a sufficient time
#1000000;
$finish;
end
initial begin
$display("Time (ns) | clk_1M | clk_100M | clk_10K | clk_20K");
$display("---------------------------------------------------");
2
repeat (50) begin // Print every 50,000 ns (adjust as needed)
#50000;
$display("%0t | %b | %b | %b | %b",
$time, clk_1M, clk_100M, clk_10K, clk_20K);
end
end
endmodule
*****************************************************************************************
Output:
******************************************************************************************
Time (ns) | clk_1M | clk_100M | clk_10K | clk_20K
---------------------------------------------------
50000000 | 1 | 1 | 0 | 1
100000000 | 1 | 1 | 1 | 1
150000000 | 0 | 0 | 0 | 1
200000000 | 0 | 1 | 1 | 1
250000000 | 1 | 1 | 0 | 1
300000000 | 1 | 0 | 1 | 1
350000000 | 1 | 1 | 0 | 1
400000000 | 0 | 1 | 1 | 1
450000000 | 0 | 0 | 0 | 1
500000000 | 1 | 1 | 1 | 1
550000000 | 1 | 1 | 0 | 1
600000000 | 1 | 0 | 1 | 1
650000000 | 0 | 1 | 0 | 1
700000000 | 0 | 1 | 1 | 1
750000000 | 0 | 0 | 0 | 1
800000000 | 1 | 1 | 1 | 1
850000000 | 1 | 1 | 0 | 1
900000000 | 0 | 0 | 1 | 1
950000000 | 0 | 1 | 0 | 1
1000000000 | 0 | 1 | 1 | 1
******************************************************************************************
3
Question 2:
**************************************************************************************************
Q2) Generate clock of 1Mhz with variable duty cycle like 25%
,50%, and 75%
******************************************************************************************
Code:
******************************************************************************************
module clock_generator (
input wire clk, // 500 MHz clock input
input wire rst, // Reset signal
input wire [1:0] duty, // 2-bit duty cycle control (00 = 25%, 01 = 50%,
10 = 75%)
output reg clk_out // 1 MHz clock output
);
integer count = 0;
integer high_time = 125; // Default to 25% (125 cycles high, 375 cycles
low)
always @(posedge clk or posedge rst) begin
if (rst) begin
count <= 0;
clk_out <= 0;
end else begin
count <= count + 1;
case (duty)
2'b00: high_time = 125; // 25% duty cycle
2'b01: high_time = 250; // 50% duty cycle
2'b10: high_time = 375; // 75% duty cycle
default: high_time = 250; // Default to 50%
endcase
if (count < high_time)
clk_out <= 1;
else
clk_out <= 0;
if (count >= 500) // Reset every 500 cycles (1 MHz)
count <= 0;
end
end
endmodule
4
Testbench:
`timescale 1ns/1ps
module tb_clock_generator;
reg clk;
reg rst;
reg [1:0] duty;
wire clk_out;
// Instantiate the clock generator module
clock_generator uut (
.clk(clk),
.rst(rst),
.duty(duty),
.clk_out(clk_out)
);
// Generate 500 MHz clock (Period = 2 ns)
always #1 clk = ~clk;
initial begin
$dumpfile("clock_generator.vcd");
$dumpvars(0, tb_clock_generator);
// Initialize signals
clk = 0;
rst = 1;
duty = 2'b00; // Start with 25% duty cycle
#10 rst = 0;
// Test different duty cycles
#500000 duty = 2'b01; // Switch to 50% duty cycle
#500000 duty = 2'b10; // Switch to 75% duty cycle
#500000 $finish;
end
initial begin
$display("Time (ns) | Duty Cycle | clk_out");
$monitor("%0t | %d%% | %b",
$time, (duty == 2'b00) ? 25 : (duty == 2'b01) ? 50 : 75,
clk_out);
end
endmodule
*****************************************************************************************
Output:
******************************************************************************************
******************************************************************************************
5
Question 3:
**************************************************************************************************
Q3) Generate two clocks of 500 Mhz with out of phase like 0, 90,
180, 270 ,360 degree as mentioned in the image below.
User can provide phase and frequency as command line argument
******************************************************************************************
Code:
******************************************************************************************
module phase_shift_clock (
input wire clk,
input wire rst,
input wire [1:0] phase,
output reg clk_out1,
output reg clk_out2
);
always @(posedge clk or posedge rst) begin
if (rst) begin
clk_out1 <= 0;
clk_out2 <= 0;
end else begin
clk_out1 <= ~clk_out1; // 500 MHz clock (Period = 2 ns)
end
end
always @(posedge clk or posedge rst) begin
if (rst)
clk_out2 <= 0;
else begin
case (phase)
2'b00: clk_out2 <= clk_out1; // 0° Phase Shift
2'b01: clk_out2 <= #0.5 clk_out1; // 90° Phase Shift (0.5
ns delay)
2'b10: clk_out2 <= #1 clk_out1; // 180° Phase Shift (1
ns delay)
2'b11: clk_out2 <= #1.5 clk_out1; // 270° Phase Shift (1.5
ns delay)
endcase
end
end
endmodule
6
Testbench:
`timescale 1ns/1ps
module tb_phase_shift_clock;
reg clk;
reg rst;
reg [1:0] phase;
wire clk_out1;
wire clk_out2;
// Instantiate the phase shift clock module
phase_shift_clock uut (
.clk(clk),
.rst(rst),
.phase(phase),
.clk_out1(clk_out1),
.clk_out2(clk_out2)
);
// Generate 1 GHz clock (Period = 1 ns) so 500 MHz toggles every 2 ns
always #1 clk = ~clk;
initial begin
$dumpfile("phase_shift_clock.vcd");
$dumpvars(0, tb_phase_shift_clock);
// Initialize signals
clk = 0;
rst = 1;
phase = 2'b00; // Start with 0° phase shift
#10 rst = 0;
// Test different phases
#100 phase = 2'b01; // 90° phase shift
#100 phase = 2'b10; // 180° phase shift
#100 phase = 2'b11; // 270° phase shift
#100 $finish;
end
initial begin
$display("Time (ns) | Phase | clk_out1 | clk_out2");
$monitor("%0t | %d° | %b | %b",
$time, (phase == 2'b00) ? 0 : (phase == 2'b01) ? 90 : (phase
== 2'b10) ? 180 : 270, clk_out1, clk_out2);
end
endmodule
*****************************************************************************************
Output:
******************************************************************************************
******************************************************************************************
7
Question 4:
**************************************************************************************************
Q4) Generate clock, frequency and duty cycle specified by user
as command line argument. If not specified by user then program
should shout appropriate message on console.
******************************************************************************************
Code:
******************************************************************************************
module clock_generator (
input wire clk, // Input reference clock
input wire rst, // Reset signal
input integer freq, // User-specified frequency in MHz
input integer duty, // User-specified duty cycle percentage
output reg clk_out // Generated clock output
);
integer high_time, low_time, period, count;
always @(posedge clk or posedge rst) begin
if (rst) begin
clk_out <= 0;
count <= 0;
end else begin
period = 1000 / freq; // Compute period in ns (assuming
1 GHz input clock)
high_time = (period * duty) / 100; // High time based on duty
cycle
low_time = period - high_time; // Low time is the rest of the
period
count = count + 1;
if (count < high_time)
clk_out <= 1;
else
clk_out <= 0;
if (count >= period) count = 0; // Reset counter after one full
cycle
end
end
endmodule
Testbench:
`timescale 1ns/1ps
module tb_clock_generator;
reg clk;
reg rst;
integer freq, duty;
wire clk_out;
// Instantiate the clock generator module
clock_generator uut (
.clk(clk),
8
.rst(rst),
.freq(freq),
.duty(duty),
.clk_out(clk_out)
);
// Generate a 1 GHz reference clock (Period = 1 ns)
always #0.5 clk = ~clk;
initial begin
// Initialize signals
clk = 0;
rst = 1;
// **Manually set frequency and duty cycle**
freq = 50; // 50 MHz
duty = 75; // 75% duty cycle
$dumpfile("clock_generator.vcd");
$dumpvars(0, tb_clock_generator);
// Release reset after setup
rst = 0;
$display("Generating Clock with Frequency: %d MHz, Duty Cycle: %d%%",
freq, duty);
#1000 $finish; // Run simulation for 1000 ns
end
initial begin
$display("Time (ns) | clk_out");
$monitor("%0t | %b", $time, clk_out);
end
endmodule
*****************************************************************************************
Output:
******************************************************************************************
******************************************************************************************