Clock frequencies testing issues with test timeout

Hi,

Testing different clock frequencies for my design, for example: 480Mhz, 320MHz and 200MHz.
So I have added in my ip_tb clk gen which can generate 3 clocks based on clk_period for each frequency.


module ip_tb
    logic _clk;
    // Clock Cycle period
    real CLK_PERIOD = 2083; //in psec units; //frequency=480MHz
    
    initial 
    begin
        automatic int unsigned frequency = 480; // in MHz, 480Mhz is default one
        
        if ($value$plusargs("CLK_FREQ=%d", frequency)) begin
            
            case (frequency)
                480 : CLK_PERIOD = 2083;    //in psec units; //frequency=480MHz
                320 : CLK_PERIOD = 3125;    //in psec units
                200 : CLK_PERIOD = 5000;    //in psec units
                default : $fatal("TB_TOP", "Unsupported frequency");
            endcase 
            
            $display($realtime," %m: Clock frequency set by Plusarg. FREQUENCY=%0d MHz. CLK_PERIOD=%0t(%0d)", frequency, CLK_PERIOD, CLK_PERIOD);
            
        end
        
        forever
        begin
            #(CLK_PERIOD/2) _clk = ~_clk;
        end
    end

endmodule 

First question:
is this the correct way, from methodology point of view, to generate clk with different frequencies?

Next problem:
I have added kind of a global timeout mechanism in my Env file + including some heartbeat prints to log, just to see if simulation is alive.
Which when expired finishes the test with uvm_fatal error.
Usually in all my tests, it was enough for the timeout to be: 1500 * 100usec.
Code below:


parameter GLOBAL_RUN_TIMEOUT = 1500;

task global_timeout();
    
    fork : WRAPPING_FORK
    
        begin : FORK_GUARD
        
            fork
                begin
                    `uvm_info(get_type_name(), $sformatf("Global_timeout_limit = %0t", (GLOBAL_RUN_TIMEOUT * 100us) ), UVM_NONE)
                    #( GLOBAL_RUN_TIMEOUT * 100us );
                end
                begin
                    forever
                    begin
                        #( plus_arg_heartbeat_interval * 50us );
                        `uvm_info(get_type_name(), $sformatf("heartbeat.. %0t to termination", (GLOBAL_RUN_TIMEOUT * 100us) - $time), UVM_NONE)
                    end
                end
            join_any
            
            disable fork;
        
        end : FORK_GUARD
    
    join : WRAPPING_FORK

    `uvm_fatal(get_type_name(), $sformatf("%m: Simulation global_timeout_limit %0t was reached", (GLOBAL_RUN_TIMEOUT * 100us) ))
    
endtask : global_timeout

But when my clock was generated with frequency=200Mhz, the timeout expired before test traffic ended.

Second question:
How can I waterfall the CLK_PEROID chosen in ip_tb to other parts of my verification environment?

If anyone can point me to some paper, or add code with good working practice to handle it will be awesome.

Thanks,
Michael

In reply to Michael54:

Hello,

**is this the correct way, from methodology point of view, to generate clk with different frequencies?
**

Yes, this is the approach, you can encapsulate this into an interface for instance, and make it reusable just by calling tasks. Anyway the approach is correct.

How can I waterfall the CLK_PEROID chosen in ip_tb to other parts of my verification environment?

You can use the config_db to share the clock period once computed in the whole DV environment.


parameter GLOBAL_RUN_TIMEOUT = 1500;
 
task global_timeout();
 
    fork : WRAPPING_FORK
 
        begin : FORK_GUARD
 
            fork
                begin
                    `uvm_info(get_type_name(), $sformatf("Global_timeout_limit = %0t", (GLOBAL_RUN_TIMEOUT * 100us) ), UVM_NONE)
                    #( GLOBAL_RUN_TIMEOUT * 100us );
                end
                begin
                    forever
                    begin
                        #( plus_arg_heartbeat_interval * 50us );
                        `uvm_info(get_type_name(), $sformatf("heartbeat.. %0t to termination", (GLOBAL_RUN_TIMEOUT * 100us) - $time), UVM_NONE)
                    end
                end
            join_any
 
            disable fork;
 
        end : FORK_GUARD
 
    join : WRAPPING_FORK
 
    `uvm_fatal(get_type_name(), $sformatf("%m: Simulation global_timeout_limit %0t was reached", (GLOBAL_RUN_TIMEOUT * 100us) ))
 
endtask : global_timeout

Honestly speaking I do not like the nested forks and on top of that I do not like using disable fork since you do not know what kind of threads or how many threads the parent spawned. I prefer opting for ending threads rather then not ending threads. Could you please summarize the reasons why you are using the code above ? why do you need a timeout while generating a clock ? Regards

In reply to Michael54:

When you are dealing with delays you should always specify the units. A comment is not enough.

Use a 2-state type bit for the clock. That removes the chance of any edge at time 0, which can lead to race conditions.

UVM already provides a heartbeat, as well as timeouts, so why do you need to invent your own.

real CLK_PERIOD = 2083ps; //frequency=480MHz

Rsignori92, The nested fork takes care of isolating the threads the disable fork affects.

Thank you: Dave, Christoph and Rsignori92,

Changed the clock signal to be 2-state type bit.


bit _clk;

And the CLK_PERIOD to be realtime.


// Clock Cycle periods
realtime CLK_PERIOD = 2083.33333ps; //in psec units; //frequency=480MHz

And will read on heartbeat and timeouts provided by UVM → thanks!

Some additional questions:

  1. How and where it is better to randomize the CLK_PERIOD,
    so I can pass it to through the uvm_config_db to the whole DV environment?
    Since my clock generator code resides inside the TB module in the initial begin end statement.

  2. I saw on the web examples of other clock generators, with high_period and low_period and also clock enable, and skew and phases.
    Is anyone familiar with a common code for clock generator that can be downloaded from the Verification Academy site or other sources?

In reply to Michael54:

The clock can be treated like any other stimulus. Search for clock driver agent.

https://verificationacademy.com/forums/uvm/how-generate-clock-driver#reply-49792