Integer - Time Conversion that actually works!
Author Message
Integer - Time Conversion that actually works!

Hello,

I was recently looking at section 4.2.8 of the VHDL FAQ, which gives the
following example of Integer - Time Conversion

http://www.*-*-*.com/ #integer_time

architecture convert of x is
signal a,c : integer:=20;
signal b : time;
begin
process
begin
wait for 1 fs;
a <= a + 1;
b <= a * 1 fs;
wait for 1 fs;
c <= b / 1 fs;
end process;
end;

I was also recently writing a test bench that some time to real
conversion, and I came to the conclusion that the above example may be
correct from the point of view of the LRM, but it doesn't work so well
with the actual tools that we use.
For example, Modelsim uses a 64 bit signed integer to represent time (*
see footnote) but it only uses 32 bit signed integers to represent the
VHDL integer type.

This means that if in the above example, b had a value greater than
2.147 us, the integer c would not get the correct value, as 2.147 us / 1
fs overflows the 32 bit integer c.
2.147 us is not a very long time!

My fix was to divide not by 1 fs, which is the smallest time step
possible in VHDL, but to divide by the smallest time step possible in my
model, which was half the clock cycle.  (Obviously if  multiple clocks
are used, this wouldn't work quite so well.)
I felt this was much better than just guessing some fixed value in ps,
ns or us, which may not scale well with changes in clock rate.
Besides, I already had a constant that defined half the test clock
frequency.

The following code fragments are from my testbench, which I have tested
to be robust (in terms of accuracy) over widely varying simulation
periods, using two different simulators (Modelsim and Simili):

generic (
f_in     : real;  -- Hz, input frequency
);

...

constant clock_half_period : time := (0.5e15 / f_in) * 1 fs;
constant clock_period : time := 2 * clock_half_period;
-- Normally, we would say clock_half_period := clock_period / 2;
-- but that can lose accuracy, due to the implicit floor().

...

clock_generator : process
begin
clock <= '1';
wait for clock_half_period;
clock <= '0';
wait for clock_half_period;
end process clock_generator;

...

-- Here's where I needed the Time -> Real conversion

measured_frequency <= real(number_of_outputs) /
real((now - time_of_first_output) / clock_half_period) * f_in * 2.0;

(*) You can test this by putting Modelsim into fs resolution
(vsim -t fs) and noticing that time goes negative after about 2 hours
and 33 minutes.  If you are doing any calculations involving time, these
calculations may overflow and produce rubbish answers much earlier.

I just thought I'd share my findings with you.

Regards,
Allan.          "Nine parts water, one part sand."
--

Agilent Technologies          Voice:  +61 3 9210 5527
Advanced Networks Division    Fax:    +61 3 9210 5550
347 Burwood Highway  Forest Hill 3131 Australia

Tue, 01 Jul 2003 21:16:14 GMT
Integer - Time Conversion that actually works!
On Sat, 13 Jan 2001 00:16:14 +1100, Allan Herriman

Quote:
> I was recently looking at section 4.2.8 of the VHDL FAQ, which gives the
> following example of Integer - Time Conversion
> http://www.vhdl.org/comp.lang.vhdl/FAQ1.html#integer_time
>         architecture convert of x is
>         signal a,c : integer:=20;
>         signal b : time;
>         begin
>             process
>             begin
>               wait for 1 fs;
>               a <= a + 1;
>               b <= a * 1 fs;
>               wait for 1 fs;
>               c <= b / 1 fs;
>             end process;
>         end;
> I was also recently writing a test bench that some time to real
> conversion, and I came to the conclusion that the above example may
> be correct from the point of view of the LRM, but it doesn't work so
> well with the actual tools that we use.  For example, Modelsim uses
> a 64 bit signed integer to represent time (* see footnote) but it
> only uses 32 bit signed integers to represent the VHDL integer type.
> This means that if in the above example, b had a value greater than
> 2.147 us, the integer c would not get the correct value, as 2.147 us
> / 1 fs overflows the 32 bit integer c.  2.147 us is not a very long
> time!

Converting a number to time is like converting a number to weight.
The results all depends on the scale factor you choose to employ,
since a pure number cannot represent either a time or a weight (or,
for that matter, any measurable quantity).

In the example in the FAQ (of which I am one of the authors), we had
to demonstrate the method, and so did so in fs, more or less
arbitrarily.

That's not to say that the FAQ couldn't be improved.  In particular, I
think there should be an extended discussion of what it means to
interconvert times and numbers.

However, ModelSim should detect the overflow....

Paul

--
Paul Menchini         | "There must have been a time, probably somewhere near
Menchini & Associates |  the beginning, when we could have said 'no.'"
www.mench.com         |       -- from "Rosencrantz and Guildenstern are Dead"

Wed, 02 Jul 2003 00:12:48 GMT
Integer - Time Conversion that actually works!

Quote:

> On Sat, 13 Jan 2001 00:16:14 +1100, Allan Herriman

> > I was recently looking at section 4.2.8 of the VHDL FAQ, which gives the
> > following example of Integer - Time Conversion

> > http://www.vhdl.org/comp.lang.vhdl/FAQ1.html#integer_time

> >         architecture convert of x is
> >         signal a,c : integer:=20;
> >         signal b : time;
> >         begin
> >             process
> >             begin
> >               wait for 1 fs;
> >               a <= a + 1;
> >               b <= a * 1 fs;
> >               wait for 1 fs;
> >               c <= b / 1 fs;
> >             end process;
> >         end;

> > I was also recently writing a test bench that some time to real
> > conversion, and I came to the conclusion that the above example may
> > be correct from the point of view of the LRM, but it doesn't work so
> > well with the actual tools that we use.  For example, Modelsim uses
> > a 64 bit signed integer to represent time (* see footnote) but it
> > only uses 32 bit signed integers to represent the VHDL integer type.

> > This means that if in the above example, b had a value greater than
> > 2.147 us, the integer c would not get the correct value, as 2.147 us
> > / 1 fs overflows the 32 bit integer c.  2.147 us is not a very long
> > time!

> Converting a number to time is like converting a number to weight.
> The results all depends on the scale factor you choose to employ,
> since a pure number cannot represent either a time or a weight (or,
> for that matter, any measurable quantity).

> In the example in the FAQ (of which I am one of the authors), we had
> to demonstrate the method, and so did so in fs, more or less
> arbitrarily.

> That's not to say that the FAQ couldn't be improved.  In particular, I
> think there should be an extended discussion of what it means to
> interconvert times and numbers.

> However, ModelSim should detect the overflow....

I can confirm that Modelsim definitely doesn't detect the overflow.  I
think that this was done for "efficiency" or perhaps it was done in
keeping with the C spirit.

Interestingly, if you start vsim in fs resolution, and then say:
run 9222 sec
it runs for 9222 seconds, but if you say:
run 9223 sec
it complains about not being able to run for a negative time!

Regards,
Allan.
--

Agilent Technologies          Voice:  +61 3 9210 5527
Advanced Networks Division    Fax:    +61 3 9210 5550
347 Burwood Highway  Forest Hill 3131 Australia

Fri, 04 Jul 2003 07:14:26 GMT

 Page 1 of 1 [ 3 post ]

Relevant Pages