Reputation: 289
In System-verilog one can initialize clock and make it tick by code below:
bit clk;
initial begin
clk <= 0;
end
always #CLOCK_SEMI_PERIOD begin
clk <= ~clk;
end
But what if I want to make clock ticking with some phase? For example we have two clock, with different semiperiod and I want first one to start ticking from zero, while second one ticking from $urandom_range(6)
ns.
___ ___ ___ ___
clk1 ___| |___| |___| |___| |___
____ ____ ____
clk2 _____| |____| |____| |____
I can't just write something like:
module top(output bit clk1,clk2);
parameter CLOCK1_SEMI_PERIOD = 10;
parameter CLOCK2_SEMI_PERIOD = 13;
int phase;
initial begin
clk1 <= 0;
clk2 <= 0;
phase = $urandom_range(9);
end
always #(CLOCK1_SEMI_PERIOD) begin
clk1 <= ~clk1;
end
always #(CLOCK2_SEMI_PERIOD) begin
#phase;
clk2 <= ~clk2;
end
endmodule
because it will increase second clock period by phase
ns.
Then how can I implement this kind of ticking?
Upvotes: 2
Views: 2169
Reputation: 337
Assignment skew concept can also be applied for introducing the required phase,
module top(output bit clk1,clk2);
parameter CLOCK1_SEMI_PERIOD = 10;
parameter CLOCK2_SEMI_PERIOD = 13;
int phase;
reg temp_1_clk2;//Added
wire temp_2_clk2;//Added
initial begin
clk1 <= 0;
clk2 <= 0;
phase = $urandom_range(9);
temp_1_clk2 = 0;
end
always #(CLOCK1_SEMI_PERIOD) begin
clk1 <= ~clk1;
end
always #(CLOCK2_SEMI_PERIOD) begin
temp_1_clk2 <= ~ temp_1_clk2;
end
assign #(phase) temp_2_clk2 = temp_1_clk2;//Introduces the required phase
always @(temp_2_clk2) begin //Output the clock
clk2 = ~ temp_2_clk2;
end
endmodule
Also let me know if there is any complication with above code or if any optimisation could be done
Thank you !
Upvotes: 2
Reputation: 42788
Use an initial/forever
loop
initial begin
clk1 <= 0;
clk2 <= 0;
phase = $urandom_range(9);
fork
forever #(CLOCK1_SEMI_PERIOD)
clk1 <= ~clk1;
#phase forever #(CLOCK2_SEMI_PERIOD)
clk2 <= ~clk2;
join
end
Upvotes: 5