S
Stephen Williams
Guest
Here's one that's been nagging me. As a Verilog compiler writer
I've been making my high-horse statements, but the consequences
are starting to hit home, so I wonder how this issue is dealt
with in the real world.
Here's my degenerate example:
module main;
reg foo = 0;
reg bar;
always @(foo) bar = !foo;
initial begin
#1 $display("foo=%b, bar=%b", foo, bar);
$finish;
end
endmodule // main
Salient features are the initialization assignment, and the
combinational calculation of bar from foo. (Yes, I know I can
use continuous assignment, but I'm trying to make a complicated
point with a simple example.)
This makes two threads:
initial foo = 0;
always @(foo) bar = !foo;
Run with Icarus Verilog, the $display prints foo=0 and bar=x.
Why? Because there is a time-0 race here. The initialization of
foo=0 is executed before the "always...", which means the "@(foo)"
enters seeing a 0 value, and no change. The included statement is
therefore not executed.
Now that behavior is perfectly correct, until some unsuspecting
hardware engineer (I'm a software guy!) uses always statements
to model combinational logic. A true model of combinational
logic would start at time-0 with an initial pass through the
always block, and then wait.
Or, the scheduler would somehow magically know that this thread
is to be started before the "initial" thread.
So I considered making a "quality of implementation" hack to
Icarus Verilog to have it start these so-called combinational
threads first, before any other threads, so that the @(...)
is guaranteed to be entered before anything else happens. I
would use a heuristic such as "always statements that contain
@(...) with no edges start first" to get the desired effect.
(SystemVerilog adds the always_comb keyword to call out these
sorts of threads explicitly.) I can also use attributes to
tweak scheduling in a similar fashion.
So what do the Big Guys do about this sort of thing?
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
I've been making my high-horse statements, but the consequences
are starting to hit home, so I wonder how this issue is dealt
with in the real world.
Here's my degenerate example:
module main;
reg foo = 0;
reg bar;
always @(foo) bar = !foo;
initial begin
#1 $display("foo=%b, bar=%b", foo, bar);
$finish;
end
endmodule // main
Salient features are the initialization assignment, and the
combinational calculation of bar from foo. (Yes, I know I can
use continuous assignment, but I'm trying to make a complicated
point with a simple example.)
This makes two threads:
initial foo = 0;
always @(foo) bar = !foo;
Run with Icarus Verilog, the $display prints foo=0 and bar=x.
Why? Because there is a time-0 race here. The initialization of
foo=0 is executed before the "always...", which means the "@(foo)"
enters seeing a 0 value, and no change. The included statement is
therefore not executed.
Now that behavior is perfectly correct, until some unsuspecting
hardware engineer (I'm a software guy!) uses always statements
to model combinational logic. A true model of combinational
logic would start at time-0 with an initial pass through the
always block, and then wait.
Or, the scheduler would somehow magically know that this thread
is to be started before the "initial" thread.
So I considered making a "quality of implementation" hack to
Icarus Verilog to have it start these so-called combinational
threads first, before any other threads, so that the @(...)
is guaranteed to be entered before anything else happens. I
would use a heuristic such as "always statements that contain
@(...) with no edges start first" to get the desired effect.
(SystemVerilog adds the always_comb keyword to call out these
sorts of threads explicitly.) I can also use attributes to
tweak scheduling in a similar fashion.
So what do the Big Guys do about this sort of thing?
--
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."