# Clock Period using Verilog code

I want to calculate time period by using Verilog code. Is this the correct way to get time period of clock of a particular frequency? Please suggest to me some better Verilog code. The code is not working.

I have written this sample code:

module clk(reg gsclk, output reg time1,output time2,output gs_clk_period)

always@(posedge gsclk)time1=$current_time; always@(negedge gsclk)time2=$current_time;

always@(posedge gsclk)gs_clk_period = (time2 - time1)*2;

$display("%clock %b",gs_clk_period); endmodule  I have to use time period for synthesize and want to run in real device. • Could you explain more why you are doing this? Are you trying to determine how fast your simulation is running or do you want something you can synthesize and run in a real device? – The Photon Jan 26 '13 at 16:55 • I have to use time period for synthesize and want to run in real device.This will be use like for example , Vout(n) T = gsclk*2, Vout(n)=gsclk*3 like wise in my program. – Manzer Jan 26 '13 at 17:04 ## 3 Answers Verilog offers three system tasks related to the simulation timestep: $time returns the current time as a 64-bit integer, in units of the timestep defined by the timescale directive.

$stime returns the same value as a 32-bit integer. $realtime returns the same value as a real number.

However none of these system directives are likely to be useful for synthesis. They would normally be implemented by special code in the simulator that accesses variables in the simulator program.

To keep track of time in a real circuit, you need to start with an input clock with a known frequency. For good accuracy you'd generate this with a crystal oscillator circuit, which would be entirely outside your device if you're working on an FPGA.

Then you simply build a counter to keep track of ticks of your clock (note code not tested):

module time_counter(input clk, input rst, output reg [31:0] ticks)

always @(posedge clk or posedge rst) begin
if (rst) begin
ticks <= 32'h00000000;
end
else begin
ticks <= ticks + 1;
end
end
endmodule


There is a limit to how fast a counter like this can operate, and various tricks to build faster counters if needed.

If you need to find the period of an input with an unknown period, you need to compare it to a clock with a known period. It's simplest conceptually to make the known clock much faster than the unknown clock and count ticks of the known clock for each period of the unknown clock. If that's not possible, you can divide the unknown clock by some factor (say 16 or 128 or 1024) and count ticks of the known clock for each cycle of the divider to work out the unknown period.

• But my question is how to get time period of clock?I mean frequency calculation.If the frequency of clock is 10 mhz, i want to calculate in timeperiod in ns in verilog code?? – Manzer Jan 26 '13 at 18:11
• You need to have another clock with known period. Count how many periods of the known clock make one (or 16 or 128 or 1024) period of the unknown clock. But the details of how to do it, beyond what I've already answered, depend on knowing more about your application --- what frequency range are you trying to measure? What technology are you using? etc. – The Photon Jan 26 '13 at 18:27

For it to be synthesize you need a reference clock that you already know the real period (e.g. ref_clk), then you can estimate the period of any other clock.

You'll need an counter (e.g. gs_cnt) that is incremented by gsclk. Let the counter run for ref_cnt number of ref_clk cycles. The period of gsclk can be estimated as ref_period*ref_cnt/gs_cnt.

It is a good idea to prevent the counter from rolling back to 0 while incrementing. This also lets you know that the gsclk is to fast to be measured in the ref_cnt window.

Your code assumes that the clock has 50% duty cycle. Instead you should sample twice in an always block:

module clk(reg gsclk, output reg time1,output time2,output gs_clk_period)
time rising_edge;

always @(posedge gsclk)
begin
rising_edge = $time; @(posedge gsclk) gs_clk_period =$time - rising_edge;
end

endmodule
`