|
From: Cary R. <cy...@ya...> - 2015-05-30 17:55:47
|
Hi Orson,
We should look at the standard because this could be a bug in Icarus, though I certainly understand how it could have been missed in Icarus, the standard or other simulators.
My analysis is that in the main module since the time scale is 1ps we have a value of 1,000 in the a variable. It is possible that time variables that are passed are not to be scaled as the current behavior does or it could be that we are supposed to scale the value using the caller and called routines time scale and precision. Depending on how VHDL time variables work we could end up with a difference because of the scaling that Verilog specifies.
We absolutely cannot just start putting arbitrary time scales or precisions on modules to make things work if they have already been given a timescale directive since that changes how time values are scaled/rounded in the module and that must work as specified by the standard (e.g. lets say you have a raw delay of #1.1 in the called routine).
Cary
On Saturday, May 30, 2015 9:46 AM, Maciej Sumiński <mac...@ce...> wrote:
Hi Steve,
Sorry, the message might have been a bit confusing. I use time literals,
I agree that is the right way to go. "wait for 10ns" simply becomes
"#10ns" and everything is clear.
Vhdlpp analyzes time literals used in a unit and stores the smallest
time unit in `timescale directive. To illustrate: if there are "wait for
30 ns" and "wait for 10 ps" statements, then the output is preceded with
"`timescale 1ps/1ps". I do not insist on merging this particular commit,
just thought it might be a better idea than using the default 1s/1s setting.
The main problem I had was caused by transferring time values via ports
between modules using different timescales. For example:
----------------------
`timescale 1ns/1ns
module mod(input time a);
always @(a) begin
#(a + 1ns) $display($time);
end
endmodule
`timescale 1ps/1ps
module mod_test;
time a;
mod dut(a);
initial begin
a = 1ns;
end
endmodule
----------------------
I would expect the code to display either "2" (ns) or "2000" (ps), but
the output is "1001". I checked it with another, very common simulator
and the result was the same.
I am trying to workaround the problem by overriding all `timescale
directives with one passed to iverilog command. Perhaps it could be
useful for pure (System)Verilog simulations as well.
Regards,
Orson
On 05/29/2015 09:53 PM, Stephen Williams wrote:
>
> Hmm... I haven't been paying attention, so forgive me while I try
> to catch up.
>
> As for using VHDL constants that are time values, is there a reason
> you cannot translate them to SystemVerilog time literals? Those are
> valid and correct no matter the `timescale setting for a given module.
> That is why they were invented for SystemVerilog.
>
> On 05/29/2015 09:34 AM, Maciej Sumiński wrote:
>> Hi,
>
>> I have managed to implement time and wait for/on/until statements
>> in vhdlpp [1] with tests [2].
>
>> I have chosen yet another way that seems much simpler. By default
>> vhdlpp analyzes time expressions used in the processed file and
>> then stores the required time precision in `timescale directive.
>
>> This approach does not solve the problem of different timescales
>> in modules. Therefore there is an additional option for iverilog &
>> ivlpp to override `timescale directives. This way all time
>> expressions use the same format and everything works as expected. I
>> guess it might be useful also for (System)Verilog simulations as
>> well.
>
>> Regards, Orson
>
>> 1. https://github.com/steveicarus/iverilog/pull/70 2.
>> https://github.com/orsonmmz/ivtest/tree/time_test
>
>> On 05/23/2015 12:26 AM, Martin Whitaker wrote:
>>> Your second option is standard SystemVerilog, so that is the best
>>> way to go. For accuracy, you should probably store time constants
>>> as a mantissa + exponent.
>>>
>>> Martin
>>>
>>> Maciej Sumiński wrote:
>>>> Hi,
>>>>
>>>> I am looking for the best way to implement expressions related
>>>> to time in vhdlpp. Ideally, I would use SystemVerilog's time
>>>> literals, so:
>>>>
>>>> wait for 10 ns;
>>>>
>>>> is translated to:
>>>>
>>>> #10ns;
>>>>
>>>> This ought to be trivial with the current ivl version. The only
>>>> obstacle I face now is to support constants, like:
>>>>
>>>> constant a : time := 10 ns;
>>>>
>>>> The problem here is how to use them in SystemVerilog modules
>>>> that may have different time scales.
>>>>
>>>> * First option One solution that is easy for me to implement is
>>>> to prepare an Icarus-specific function that takes mantissa and
>>>> exponent to describe a time period:
>>>>
>>>> localparam a = $ivl_time(10, -9);
>>>>
>>>> Then during elaboration the value would be adjusted according
>>>> to the time scale of scope where it is used.
>>>>
>>>> * Second option While the first approach satisfies my needs,
>>>> there might be a solution that you find more advantageous. It
>>>> also does not introduce any Icarus-specific functions.
>>>>
>>>> Though it is not available at the moment, it should be fairly
>>>> easy to make localparam accept time literals, so the initial
>>>> example becomes:
>>>>
>>>> localparam a = 10ns;
>>>>
>>>> but the current implementation stores time as floating point
>>>> numbers adjusted to the time scale of the scope where a delay
>>>> was defined [1].
>>>>
>>>> In order to use a localparam value in a scope that uses a
>>>> different time scale, the absolute time value has to be
>>>> preserved and adjusted during elaboration (just like $ivl_time
>>>> would do). To do so, I may either introduce a new type
>>>> (veritime?), or assume time values are saved in femtoseconds.
>>>>
>>>> Do you have any thoughts/preference?
>>>>
>>>> Regards, Orson
>>>>
>>>> 1.
>>>> https://github.com/steveicarus/iverilog/blob/master/parse.y#L2782
>
>
>
>
------------------------------------------------------------------------------
_______________________________________________
Iverilog-devel mailing list
Ive...@li...
https://lists.sourceforge.net/lists/listinfo/iverilog-devel
|