Localparam causes wrong time delay

Hi, running the code below results incorrect 10ps clock period instead of 10ns
if i remove the localparam, the clock period is 10ns
if i add timescale directive in p.sv, the clock period is 10ns
if i remove the timescale directive in tb.sv, the period is 10ns
if i convert the class to a module, vsim raises error.
(vsim-3009) [TSCALE] - Module 'm' does not have a timeunit/timeprecision specification in effect, but other modules do.
Can you explain what is happening here. Is this behavior tool specific.
About error 3009. Do you still need to use timescale directive even if all delays use time riterals. (e.g. #(10ns); )
Why is the clock period 10ns when i remove the timescale directive from tb.sv?
Why the use of localparam changes the clock period?
Thanks in advance.

p.sv

// `timescale 1ps/1ps

package p;

    class c;

        virtual interface i i1;

        localparam real T = 5ns;
        // real T = 5ns;

        task run();
            forever begin
                i1.clk <= 1;
                #(T);
                i1.clk <= 0;
                #(T);
            end
        endtask

    endclass

endpackage

interface i;
    logic clk;
endinterface

tb.sv

`timescale 1ps/1ps

import p::*;

module tb;

    i i1();

    c c1;

    initial begin

        c1 = new();
        c1.i1 = i1;

        fork
            begin
                c1.run();
            end
            begin
                repeat(10) @(posedge i1.clk) begin
                    $display("$time = %t", $time);
                end
            end
        join_any

        $finish;
    end

endmodule

The code above is compiled and ran like this.

vlog p.sv
vlog tb.sv
vsim work.tb -voptargs=+acc -do ‘run -all;’

I am unable to replicate the behavior you believe you’re observing (you didn’t provide us with any output). For me, the clock period remains constant at 10 ns.

It would help to use this statement before displaying any time values.

 $timeformat(-9,3,"ns",5);

You must use a timescale directive or timeunit statement when using a time literal (10ns) or delay (#10) or both (#10ns). Time literals get scaled to the local time scale/unit. 10ns becomes the value 10000 is the local time is in ps. Delays get scaled to the global time precision which is the smallest time precision of any local time precision.

Mixing design elements, such as modules, packages, and interfaces, where some have a specified timescale while others don’t, should be considered an error. However, there are various tool-specific behaviors that apply default timescales.

Hi Dave,
You can replicate the behavior in the following link.
https://edaplayground.com/x/UD9X

i added $timeformat(-9,3,“ns”,5); statement as well, the difference is visible in both text output and in the waveform.

Since i am using time literals inside delay statements. (#10ns). i thought, it wont matter what the timeunit is because 10ns will be converted to 10000 if the timescale is 1ps or to 10 if the timescale is 1ns. So the delay will always be 10ns. So i did not set the timeunit in p.sv.

If i omit setting the timeunit, will the simulator choose a default one while compiling the module? If i manually set the timeunit to different values in p.sv, the delay always become 10ns.

Do you think questa should raise the error 3009 for packages as well, like modules and interfaces?

Thanks for your time.