steveicarus / iverilog

Icarus Verilog
https://steveicarus.github.io/iverilog/
GNU General Public License v2.0
2.86k stars 530 forks source link

VPI: reading time properties #1172

Closed r2com closed 1 month ago

r2com commented 1 month ago

if all my verilog files have: `timescale 100 ns / 1 ps

and i ran this:

     int precision =  vpi_get(vpiTimePrecision, nullptr);
     int timeunit =  vpi_get(vpiTimeUnit, nullptr);
    printf("precision = %d\n", precision);
    printf("timeunit = %d\n", timeunit);

then it printed: precision = -12 timeunit = -12

if I change my timing directives in .v files to: `timescale 100 ns / 1 ns its going to print: precision = -9 timeunit = -9

so for precision, it does print it properly, however; what i noticed is it does not matter what you set timeunit to, the timeunit will be printed same as precision, as if for some reason precision defines timeunit as well..

is it a bug or am I missing something?

because for something say with: `timescale 1 ns / 1 ps i am expecting it to tell me that precision is -12 and timeunit is -9, but it gives: precision = -12 timeunit = -12

caryr commented 1 month ago

You have to specify a scope to get this to work as you are expecting. If a NULL scope is given then you get the smallest precision used in the simulation which is called the simulation time unit. This is described in the standard (see vpi_get() and "simulation time unit"

For example if you have a `timescale 1ns/10ps in one file and then `timescale 1us/1ps in another the NULL scope will return 1ps, but any module declared after the given time scales would return the appropriate unit and precision that is in effect when it is parsed.

r2com commented 1 month ago

specify scope where? what exactly you mean by specify scope? also I have only two .v files, and both of them have same setting, I do get proper precision, but timeunit is equaling the precision for some reason.

caryr commented 1 month ago

Like I said in my earlier reply, your understanding of how this works is incorrect and this is described fully in the standard. There is no global (NULL object/scope) precision or time unit. The only global value is the simulation time unit and both the vpiTimeUnit/Precision properties return the same value. See the excerpts from the 1800-2023 standard below:

3.14.3 Simulation time unit

The global time precision, also called the simulation time unit, is the minimum of all the timeprecision statements, all the time precision arguments to timeunit declarations, and the smallest time precision argument of all the `timescale compiler directives in the design.

38.6 vpi_get()

Syntax: vpi_get(prop, obj)

... For object property vpiTimeUnit or vpiTimePrecision, if the object is NULL, then the simulation time unit shall be returned. ...

r2com commented 1 month ago

well ok, i didnt find it first because I was looking into Verilog LRM. 1364-2005 (not the one you quoted here) thanks

martinwhitaker commented 1 month ago

In 1364-2005 the corresponding text is in section 19.8 and section 27.6.