Regarding real numbers in SV

I have following code ::


`timescale 1ns / 1ps 

module  top ;
  
  real T ;
  
  initial  begin
    
    T  =  ( 55 / 100 ) ; 
    
    $display(" T is %0f ",T);
    
    T  =  55.55 ; 
    
    $display(" T is %0f ",T);
    
    T  =  0.005 * 55.55 ; 
    
    $display(" T is %0f ",T);
    
    T = 1fs ;  //  Time Literal would be scaled to time unit ( LRM Section 5.8 )
    
    $display(" T is %0f ",T);
    
  end  
  
endmodule  

The O/P I observe is ::
T is 0.000000
T is 55.550000
T is 0.277750
T is 0.000001

I have a few questions

[Q1] Does the time_unit and time_precision come into picture for the code ?

[Q2] Since time_precision is 1ps , real numbers are rounded up to 3 decimal places .

How is it that for the 3rd display I observe :: 0.277750 i.e up to 6 decimal places

[Q3] For 1st O/P why is it that I observe 0.000000 .

  Even  if  I  add  real  type cast i.e  **real'( 55 / 100 )**  I  still  observe  0.000000

[Q4] For 2nd and 3rd assignment , T has values 55.550000 and 0.277750 respectively . Can I say these are 55.55ns and 0.27775ns ?

What if I change the timescale to :: `timescale 10 ns / 1 ps

  1. Time scales/units only matter in places where expressions get interpreted as delays. (procedural and continuous assignment delays, timing checks, numeric time literals. 1fs is 1 * 10-6 ns.
  2. Time precision has no effect on rounding of real data types.
  3. You are performing an integer division because its two operands are integers. Any fractional result gets truncated to 0, and then the result gets implicitly cast to a real. Adding an explicit cast of the result to real does not change the fact that you are sill doing integer division. One or bother division operands must be real to perform real division.
  4. No. They are just values until used in a delay construct.

In reply to dave_59:

Hi Dave ,

For 4th O/P as 1fs is 10-6 * 1ns ( time_unit is 1ns )** I observe O/P as T is 0.000001 .

However if I change the directive to `timescale 10ns / 1ps ,
why is it that I observe T is 0.000000 ?

I expected O/P as 0.0000001 as 1fs is 10-7 * 10ns ( time_unit is 10ns )**

In reply to hisingh:

Display with %g

In reply to dave_59:

Thanks Dave . Using %e / %g gives the intended result .

The issue seems to be due to limitations with %f ( which Displays real numbers in a decimal format )

LRM says output for decimal format depends on the Size of the expression .


LRM 21.2.1.3 ::  " For example, the result of a 12-bit expression would be allocated four characters when displayed in decimal format because the largest possible value for the expression is 4095 (decimal). "

How is the real data type treated ( Size wise ) ?

In reply to hisingh:

The f in
%f
stands for fixed-point decimal. The C/C++ convention prints 6 decimal places. You need 7. You would need the format “%9.7f”

In reply to dave_59:

Is there any way to find if the real number is odd or even ?

Thanks,
Sunanda

In reply to dave_59:

Thanks Dave .

In reply to sunanda_kommi:

Even and odd is only defined for integers.