0
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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? \$\endgroup\$
    – The Photon
    Jan 26, 2013 at 16:55
  • \$\begingroup\$ 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. \$\endgroup\$
    – Manzer
    Jan 26, 2013 at 17:04

3 Answers 3

2
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ 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?? \$\endgroup\$
    – Manzer
    Jan 26, 2013 at 18:11
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – The Photon
    Jan 26, 2013 at 18:27
  • \$\begingroup\$ @ThePhoton I also have the same question. I want to find the time period of some unknown incoming frequency having a maximum limit of 9khz. My internal clock is of 100mhz. Can you tell me how to calculate the time period in us. I am trying to write a synthesizable code which will be implemented using Nexys3 board. \$\endgroup\$ Oct 31, 2022 at 14:22
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.