|
From: Galen S. <ga...@se...> - 2019-08-09 00:28:54
|
Hello again, In order to track down the commit that caused the behavior change between 0.9 and 0.10 that is being discussed in another thread, I'd like to run iverilog and vvp without installing. I have tried using the '-B' option, but doing the obvious thing of setting it to the top of the build directory doesn't seem to work. What is the correct way to do this? thanks, galen -- Galen Seitz ga...@se... |
|
From: Evan L. <sa2...@cy...> - 2019-08-09 09:11:37
|
On 09/08/2019 01:28, Galen Seitz wrote: > Hello again, > > In order to track down the commit that caused the behavior change > between 0.9 and 0.10 that is being discussed in another thread, I wouldn't bother. If Martin's right (and I'm sure he is) then this is a 'feature' in the Lattice model, and whether or not Q initialises correctly is just a roll of the dice (but probably deterministic for a given simulator). You may be able to find a switch on one of the other simulators to randomise the initialisation order, which would be interesting - you should find that Q resets on some runs but not on others (Steve wanted to do this for Icarus, but I don't think it ever happened). This is exactly what SV's 'always_comb' is meant to fix. This was a very late attempt to rationalise simulation start-up in Verilog (to, curiously, exactly what VHDL had done since day #1). |
|
From: Martin W. <ic...@ma...> - 2019-08-09 18:42:01
|
On 09/08/19 10:11, Evan Lavelle wrote: > On 09/08/2019 01:28, Galen Seitz wrote: >> Hello again, >> >> In order to track down the commit that caused the behavior change between 0.9 and 0.10 that is >> being discussed in another thread, > > I wouldn't bother. If Martin's right (and I'm sure he is) then this is a 'feature' in the Lattice > model, and whether or not Q initialises correctly is just a roll of the dice (but probably > deterministic for a given simulator). You may be able to find a switch on one of the other > simulators to randomise the initialisation order, which would be interesting - you should find that > Q resets on some runs but not on others (Steve wanted to do this for Icarus, but I don't think it > ever happened). > > This is exactly what SV's 'always_comb' is meant to fix. This was a very late attempt to rationalise > simulation start-up in Verilog (to, curiously, exactly what VHDL had done since day #1). And indeed, replacing the "always @ QB" with "always_comb" fixes the problem. However, Icarus tries to protect the user against such problems by preferentially scheduling "always" processes ahead of "initial" processes at time 0. The reason it is not working in this case is that the initial process in a UDP is handled differently to normal initial processes, and in v10 and later is being scheduled ahead of the "always" processes. Although this is legal behaviour, I will look at changing it to restore the more user-friendly behaviour of v0.9. |
|
From: Martin W. <ic...@ma...> - 2019-08-09 20:16:27
|
Martin Whitaker wrote: > On 09/08/19 10:11, Evan Lavelle wrote: >> On 09/08/2019 01:28, Galen Seitz wrote: >>> Hello again, >>> >>> In order to track down the commit that caused the behavior change >>> between 0.9 and 0.10 that is being discussed in another thread, >> >> I wouldn't bother. If Martin's right (and I'm sure he is) then this is a >> 'feature' in the Lattice model, and whether or not Q initialises >> correctly is just a roll of the dice (but probably deterministic for a >> given simulator). You may be able to find a switch on one of the other >> simulators to randomise the initialisation order, which would be >> interesting - you should find that Q resets on some runs but not on >> others (Steve wanted to do this for Icarus, but I don't think it ever >> happened). >> >> This is exactly what SV's 'always_comb' is meant to fix. This was a very >> late attempt to rationalise simulation start-up in Verilog (to, >> curiously, exactly what VHDL had done since day #1). > > And indeed, replacing the "always @ QB" with "always_comb" fixes the problem. > > However, Icarus tries to protect the user against such problems by > preferentially scheduling "always" processes ahead of "initial" processes > at time 0. The reason it is not working in this case is that the initial > process in a UDP is handled differently to normal initial processes, and in > v10 and later is being scheduled ahead of the "always" processes. Although > this is legal behaviour, I will look at changing it to restore the more > user-friendly behaviour of v0.9. I've pushed the change to both the master and v10 branches. |
|
From: Galen S. <ga...@se...> - 2019-08-09 22:54:01
|
On 8/9/19 1:16 PM, Martin Whitaker wrote: > Martin Whitaker wrote: >> On 09/08/19 10:11, Evan Lavelle wrote: >>> On 09/08/2019 01:28, Galen Seitz wrote: >>>> Hello again, >>>> >>>> In order to track down the commit that caused the behavior change >>>> between 0.9 and 0.10 that is being discussed in another thread, >>> >>> I wouldn't bother. If Martin's right (and I'm sure he is) then this >>> is a 'feature' in the Lattice model, and whether or not Q initialises >>> correctly is just a roll of the dice (but probably deterministic for >>> a given simulator). You may be able to find a switch on one of the >>> other simulators to randomise the initialisation order, which would >>> be interesting - you should find that Q resets on some runs but not >>> on others (Steve wanted to do this for Icarus, but I don't think it >>> ever happened). >>> >>> This is exactly what SV's 'always_comb' is meant to fix. This was a >>> very late attempt to rationalise simulation start-up in Verilog (to, >>> curiously, exactly what VHDL had done since day #1). >> >> And indeed, replacing the "always @ QB" with "always_comb" fixes the >> problem. >> >> However, Icarus tries to protect the user against such problems by >> preferentially scheduling "always" processes ahead of "initial" >> processes at time 0. The reason it is not working in this case is that >> the initial process in a UDP is handled differently to normal initial >> processes, and in v10 and later is being scheduled ahead of the >> "always" processes. Although this is legal behaviour, I will look at >> changing it to restore the more user-friendly behaviour of v0.9. > > I've pushed the change to both the master and v10 branches. I have tested my code using master, and the issue is resolved. Thanks for the quick fix/workaround. It's unfortunate that the Lattice model was written in this way, but I'm certain I would have zero chance of getting them to make a change. FWIW, here's a simplified simulation that has all of the Lattice code removed. I substituted a simple toggle sequential UDP for the Lattice flip-flop. This has both a reg that is assigned in an initial block and a UDP output that has an initial statement. Each feeds an 'always @ sig' block. <https://www.edaplayground.com/x/3S7P> galen -- Galen Seitz ga...@se... |
|
From: Galen S. <ga...@se...> - 2019-08-09 20:26:08
|
On 8/9/19 1:16 PM, Martin Whitaker wrote: > Martin Whitaker wrote: >> On 09/08/19 10:11, Evan Lavelle wrote: >>> On 09/08/2019 01:28, Galen Seitz wrote: >>>> Hello again, >>>> >>>> In order to track down the commit that caused the behavior change >>>> between 0.9 and 0.10 that is being discussed in another thread, >>> >>> I wouldn't bother. If Martin's right (and I'm sure he is) then this >>> is a 'feature' in the Lattice model, and whether or not Q initialises >>> correctly is just a roll of the dice (but probably deterministic for >>> a given simulator). You may be able to find a switch on one of the >>> other simulators to randomise the initialisation order, which would >>> be interesting - you should find that Q resets on some runs but not >>> on others (Steve wanted to do this for Icarus, but I don't think it >>> ever happened). >>> >>> This is exactly what SV's 'always_comb' is meant to fix. This was a >>> very late attempt to rationalise simulation start-up in Verilog (to, >>> curiously, exactly what VHDL had done since day #1). >> >> And indeed, replacing the "always @ QB" with "always_comb" fixes the >> problem. >> >> However, Icarus tries to protect the user against such problems by >> preferentially scheduling "always" processes ahead of "initial" >> processes at time 0. The reason it is not working in this case is that >> the initial process in a UDP is handled differently to normal initial >> processes, and in v10 and later is being scheduled ahead of the >> "always" processes. Although this is legal behaviour, I will look at >> changing it to restore the more user-friendly behaviour of v0.9. > > I've pushed the change to both the master and v10 branches. Thanks, I'll give it a try. Regarding the question in the subject line, do you have a preferred way of running iverilog and vvp when you are working on the Icarus code? galen -- Galen Seitz ga...@se... |
|
From: Martin W. <ic...@ma...> - 2019-08-09 20:35:24
|
Galen Seitz wrote: > On 8/9/19 1:16 PM, Martin Whitaker wrote: >> Martin Whitaker wrote: >>> On 09/08/19 10:11, Evan Lavelle wrote: >>>> On 09/08/2019 01:28, Galen Seitz wrote: >>>>> Hello again, >>>>> >>>>> In order to track down the commit that caused the behavior change >>>>> between 0.9 and 0.10 that is being discussed in another thread, >>>> >>>> I wouldn't bother. If Martin's right (and I'm sure he is) then this is >>>> a 'feature' in the Lattice model, and whether or not Q initialises >>>> correctly is just a roll of the dice (but probably deterministic for a >>>> given simulator). You may be able to find a switch on one of the other >>>> simulators to randomise the initialisation order, which would be >>>> interesting - you should find that Q resets on some runs but not on >>>> others (Steve wanted to do this for Icarus, but I don't think it ever >>>> happened). >>>> >>>> This is exactly what SV's 'always_comb' is meant to fix. This was a >>>> very late attempt to rationalise simulation start-up in Verilog (to, >>>> curiously, exactly what VHDL had done since day #1). >>> >>> And indeed, replacing the "always @ QB" with "always_comb" fixes the >>> problem. >>> >>> However, Icarus tries to protect the user against such problems by >>> preferentially scheduling "always" processes ahead of "initial" >>> processes at time 0. The reason it is not working in this case is that >>> the initial process in a UDP is handled differently to normal initial >>> processes, and in v10 and later is being scheduled ahead of the "always" >>> processes. Although this is legal behaviour, I will look at changing it >>> to restore the more user-friendly behaviour of v0.9. >> >> I've pushed the change to both the master and v10 branches. > > Thanks, I'll give it a try. > > Regarding the question in the subject line, do you have a preferred way of > running iverilog and vvp when you are working on the Icarus code? > I always run 'make install'. If you don't want to affect your working installation, run configure with the --prefix option to set the installation root to someplace else, or with the --suffix option to make the filenames unique. If you want to keep multiple builds for comparison, you can build out-of-tree. |
|
From: Evan L. <sa2...@cy...> - 2019-08-10 09:20:41
|
On 09/08/2019 19:17, Martin Whitaker wrote: > However, Icarus tries to protect the user against such problems by > preferentially scheduling "always" processes ahead of "initial" > processes at time 0. Wow. Never heard of that before. I wonder if other vendors do that? |
|
From: Galen S. <ga...@se...> - 2019-08-11 00:31:07
|
On 8/10/19 2:05 AM, Evan Lavelle wrote: > On 09/08/2019 19:17, Martin Whitaker wrote: > >> However, Icarus tries to protect the user against such problems by >> preferentially scheduling "always" processes ahead of "initial" >> processes at time 0. > > Wow. Never heard of that before. I wonder if other vendors do that? For the case that we've been discussing, I don't understand why it isn't always deterministic. Given the code below, doesn't the initial block generate an update event at time 0, and doesn't that cause the NBA inside the always block to be scheduled? If that is true, then when a sequential UDP with an initial statement is substituted for the initial block below, then doesn't the same logic apply? reg a; reg y; initial begin a = 0; end always @(a) begin y <= a; end thanks, galen -- Galen Seitz ga...@se... |
|
From: Martin W. <ic...@ma...> - 2019-08-11 07:43:05
|
Galen Seitz wrote:
> On 8/10/19 2:05 AM, Evan Lavelle wrote:
>> On 09/08/2019 19:17, Martin Whitaker wrote:
>>
>>> However, Icarus tries to protect the user against such problems by
>>> preferentially scheduling "always" processes ahead of "initial"
>>> processes at time 0.
>>
>> Wow. Never heard of that before. I wonder if other vendors do that?
>
> For the case that we've been discussing, I don't understand why it isn't
> always deterministic. Given the code below, doesn't the initial block
> generate an update event at time 0, and doesn't that cause the NBA inside
> the always block to be scheduled? If that is true, then when a sequential
> UDP with an initial statement is substituted for the initial block below,
> then doesn't the same logic apply?
>
> reg a;
> reg y;
>
> initial begin
> a = 0;
> end
>
> always @(a) begin
> y <= a;
> end
From the IEEE standard:
"The initial and always constructs are enabled at the beginning of a
simulation. The initial construct shall execute only once, and its activity
shall cease when the statement has finished. In contrast, the always
construct shall execute repeatedly. Its activity shall cease only when the
simulation is terminated. There shall be no implied order of execution
between initial and always constructs. The initial constructs need not
be scheduled and executed before the always constructs."
So if the initial construct executes before the always construct, the
procedural timing control "@(a)" won't have been executed when the
assignment to "a" occurs, so won't be waiting for an update event.
It may help to explain that
always @(a) begin
y <= a;
end
is exactly equivalent to
always begin
@(a) y <= a;
end
i.e. the "@(a)" is part of the first statement executed by the always
construct, not something that is continually active.
Given that other simulators don't suffer from this race, it seems quite
likely that other vendors also prioritise always constructs at the start of
simulation.
|
|
From: Evan L. <sa2...@cy...> - 2019-08-12 08:18:10
|
Here's one I spent a few hours on:
module test;
event done;
initial begin
// #0;
foo; // may or may not finish in zero time
-> done;
end
always @(done)
... // may or may not fire
endmodule
There's a race between event creation and event triggering, and this
code "fails" in 4/7 simulators (including Incisive). Uncommenting the #0
makes it run on all 7 simulators.
?!
|
|
From: Martin W. <ic...@ma...> - 2019-08-12 21:04:41
|
Evan Lavelle wrote: > Here's one I spent a few hours on: > > module test; > event done; > initial begin > // #0; > foo; // may or may not finish in zero time > -> done; > end > always @(done) > ... // may or may not fire > endmodule > > There's a race between event creation and event triggering, and this code > "fails" in 4/7 simulators (including Incisive). Uncommenting the #0 makes > it run on all 7 simulators. > ?! I delved into the Icarus compiler code, and found the rules for prioritising always constructs are more complex than I remembered. It tries to identify always constructs that are modelling combinatorial logic, and only prioritises those. Your example above doesn't qualify - I think because it is sensitive to an event, not a signal. I tested this example: module test(); reg i, q; initial i = 1; always @(i) q = i; initial #1 $display(q); endmodule Icarus and Riveria Pro output '1'. CVer and Veriwell output 'x'. Moving the always construct to before the initial constructs results in all four outputing '1'. |