Declaring timeunit in package

Good day.
I declare period of my clock frequensy in a package, and that’s where i define timeunit, my code looks like this:

package Clock_pkg;

timeunit 100ps;
timeprecision 1 ps;

parameter Period = 156;

endpackage

then i import this package in my testmodule:

module top;
import Clock_pkg::*;

bit clk;

always
begin
#Period/2 clk = !clk;
end


endmodule

Problem is, clk doesn’t have Period, which should be with this timeunit. So package import doesn’t import timeunit, or do i miss something?

The problem is that Period is just a value - 156, it is not a delay. When you import Period from the Clock_pkgm you are just importing the definition of its value.

The only places time-unit/precision scales a values is in a delay expression #(expr), or time literal.

You should define your period as

parameter real Period = 1.56ns/1ps; // value will be in ps 1560

And use the period as

#(Period *1ps)/2 clk = !clk;

In reply to dave_59:

Dave, could this have been written as the following, instead of what you have?

parameter realtime Period = 1560ps;

In reply to ben@SystemVerilog.us:

Not a good idea. Period will get scaled to the local timescale. Unlike VHDL, there is no physical timescale unit information saved with the value. If the local timescale was 1ns, the Period = 1.5. When you pass Period to another scope, there will be no way to know that 1.5 is in ns.

In reply to dave_59:

You should define your period as

parameter real Period = 1.56ns/1ps; // value will be in ps 1560

And use the period as
#(Period *1ps)/2 clk = !clk;

Dave, I disagree with the statement “1.56ns/1ps; // value will be in ps 1560”
If I remember my physics 101 class from way back then, the unitX_scale/unitX_scale cancel out, yielding no unit scale.
Remember the classical problem: how far have you walked if you travel at 3 mi/hr for one hour?
Answer: (3 mi x 1 hr)/hr, and the hr scale cancels out.
Thus, the comment should be:

parameter real Period = 1.56ns/1ps; // value will real with a converted value of 1560

In reply to ben@SystemVerilog.us:

Ben, with all due respect, I disagree with your disagreement.

You are forgetting that the introduction of a time literal imposes a time scale factor, and we are trying to normalize the magnitude of the value to a fixed timescale value. When you write #(Value), Verilog implicitly multiplies Value by the current timescale unit, yielding a value with a unit scale.
When you make assignment of a Value to a time variable or parameter, there is no unit scale associated with the Value, it is just a unit-less value. However, if we make an agreement that the delay expression will be written as #(Value * 1ps), then Value is expected to be units of picoseconds.

I could have written

parameter int Period = 1560; // value in ps

meaning that Period is implicitly defined with a ps unit.

Writing

parameter int Period = 1560ps; // value in ps

will be incorrect because the value will be scaled unless the current timescale is 1ps.

In reply to dave_59:

Dave,
I don’t think I communicated my point very well; specifically, you wrote:

You should define your period as
parameter real Period = 1.56ns/1ps; // value will be in ps 1560
And use the period as
#(Period *1ps)/2 clk = !clk;

My issue is with you comment “// value will be in ps 1560” and in the need
to do the operation 1.56ns/1ps
It seems to me that you could have written this instead, and be correct:
[Ben]You should define your period as
parameter real Period = 1560; // value expressed in ps
And use the period as
#(Period *1ps)/2 clk = !clk;

I say this because 1.56ns/1ps is same as 1560, and IS unit-less.
What puzzled me about you initial comment was the absolute need to do this division by 1ns, implying that without it, it would not work.

Another question about how real numbers are expressed. Shouldn’t
parameter real Period = 1560; be written as
parameter real Period = 1560.0;

5.7.2 Real literal constants
The real literal constant numbers shall be represented as described by IEEE Std 754, an IEEE standard for double-precision floating-point numbers.
Real numbers can be specified in either decimal notation (for example, 14.72) or in scientific notation (for example, 39e8, which indicates 39 multiplied by 10 to the eighth power). Real numbers expressed with a decimal point shall have at least one digit on each side of the decimal point.

The following code compiles OK, it is correct?

module m;
   real r1, r2;
   initial r1=1; // Compiles OK ??? seems incorrect to me 
   initial r2=1.0;
endmodule

In reply to ben@SystemVerilog.us:

  1. I don’t think Dave meant that there is an absolute need to write 1.56ns/1ps.He himself wrote that you could just write 1560. The point of writing it as 1.56ns/1ps is a sort of documentation as to the intention.

  2. When you assign an integer number to a real data object, the integer is implicitly converted to real.