weird simulation problems for a PC module

R

rekz

Guest
my code is the following:

module PC(in, Clk, out);

input Clk;
input[31:0] in;
output[31:0] out;
reg[31:0] out;
reg[31:0] PC;

initial
PC <= 32'b0000000000000000000000000000000;

always @(posedge Clk) begin
PC <= in;
out <= PC;
end

endmodule


it is just a code for a program counter, I've set the initial value of
the program counter to 0, however when I launch iSim and even before
running the code.. I checked the PC value and it's not 0. Why is this?
 
On Mar 8, 11:38 am, rekz <aditya15...@gmail.com> wrote:
it is just a code for a program counter, I've set the initial value of
the program counter to 0, however when I launch iSim and even before
running the code.. I checked the PC value and it's not 0. Why is this?
Before the simulation starts, regs will be in the unknown state with a
value of X. Then when the simulation starts, initial blocks will start
executing at time 0. Then PC will be set to 0 (ignoring the details of
nonblocking assignments and timing regions).

I believe the latest Verilog LRM changed the semantics of initializing
a variable when you declare it (i.e., reg PC = 32'h0;) so that it's
"born" with the initial value (0) instead of X. However, I don't know
if any simulators support this yet.

-cb
 
On Mar 8, 11:25 am, Chris Briggs <ch...@engim.com> wrote:
On Mar 8, 11:38 am, rekz <aditya15...@gmail.com> wrote:

it is just a code for a program counter, I've set the initial value of
the program counter to 0, however when I launch iSim and even before
running the code.. I checked the PC value and it's not 0. Why is this?

Before the simulation starts, regs will be in the unknown state with a
value of X. Then when the simulation starts, initial blocks will start
executing at time 0. Then PC will be set to 0 (ignoring the details of
nonblocking assignments and timing regions).

I believe the latest Verilog LRM changed the semantics of initializing
a variable when you declare it (i.e., reg PC = 32'h0;) so that it's
"born" with the initial value (0) instead of X. However, I don't know
if any simulators support this yet.

-cb
when I first run ISim and run the simulation for 1.00 micro sec I get
the following:

http://img704.imageshack.us/img704/843/32446480.jpg

but after I restart it I get the following:

http://img402.imageshack.us/img402/8907/25224512.jpg

why is that?
 
On Mar 8, 5:15 pm, rekz <aditya15...@gmail.com> wrote:
when I first run ISim and run the simulation for 1.00 micro sec I get
the following:

http://img704.imageshack.us/img704/843/32446480.jpg

but after I restart it I get the following:

http://img402.imageshack.us/img402/8907/25224512.jpg

why is that?
Don't know. Simulator bug?

-cb
 
On Mar 8, 1:25 pm, Chris Briggs <ch...@engim.com> wrote:
I believe the latest Verilog LRM changed the semantics of initializing
a variable when you declare it (i.e., reg PC = 32'h0;) so that it's
"born" with the initial value (0) instead of X.
Not necessarily "born" with it, no. Just guaranteed to be assigned it
before any initial or always blocks execute. If you look at it using
the simulator's UI before starting simulation, it may still be X.
Some simulators may execute some or all initializers at compile time,
while others may execute them at simulation time before any initial or
always blocks. Nothing wrong with either.

In some cases it wouldn't be correct to execute initializers at
compile time. For example, what if the initializer calls a function
that prints something? That should come out at simulation time.
 
sharp@cadence.com wrote:
On Mar 8, 1:25 pm, Chris Briggs <ch...@engim.com> wrote:
I believe the latest Verilog LRM changed the semantics of initializing
a variable when you declare it (i.e., reg PC = 32'h0;) so that it's
"born" with the initial value (0) instead of X.

Not necessarily "born" with it, no. Just guaranteed to be assigned it
before any initial or always blocks execute. If you look at it using
the simulator's UI before starting simulation, it may still be X.
Some simulators may execute some or all initializers at compile time,
while others may execute them at simulation time before any initial or
always blocks. Nothing wrong with either.

In some cases it wouldn't be correct to execute initializers at
compile time. For example, what if the initializer calls a function
that prints something? That should come out at simulation time.
Right, it doesn't really mean much even if it were true to say
that a variable were "born" with the initialized value. The value
will still need to be propagated through expressions, some of which
may involve system functions, user defined functions; all manner
of stuff that can't necessarily be evaluated without starting the
simulator; and some of that stuff may trigger events that might
cascade in interesting ways.

Paradoxically, the user often prefers that initializations do
*not* preceed other executions. Consider this:

integer src = 1;
integer dst;
always @(src) dst = function(src);
[...]

The "always" statement is combinational in this example, and it
is usual for the user to expect that the relation "dst = function(src)"
is invariant, at least so far as $strobe() can tell. But if the
value of "src" is propagated before all other threads, then its
propagation will happen before the "@(src) ..." is executed, and
the time-0 value for "dst" will be un-mathematical.

Icarus Verilog (and I suspect other Verilog simulators) makes a
positive effort to detect combinational "always" statements like
this and schedule them to start (and block themselves in the wait)
*before* initializations, so that combinational expressions come
out right when time-0 settles.
--
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."
 
Steven and Stephen,

Makes sense. Thanks for the clarifications.

-cb
 
On Mar 12, 3:28 pm, Stephen Williams <spamt...@icarus.com> wrote:
Paradoxically, the user often prefers that initializations do
*not* preceed other executions.
Yes, I argued this point when the committee was changing the rules to
require initializers to preceed other executions in SV. The response
was that users should be using always_comb for all combinational
always blocks, which doesn't have this problem.

  integer src = 1;
  integer dst;
  always @(src) dst = function(src);
  [...]

The "always" statement is combinational in this example, and it
is usual for the user to expect that the relation "dst = function(src)"
is invariant, at least so far as $strobe() can tell. But if the
value of "src" is propagated before all other threads, then its
propagation will happen before the "@(src) ..." is executed, and
the time-0 value for "dst" will be un-mathematical.
This is not just a time-0 issue. The value of dst will not become the
desired combinational value until src has changed from its initialized
value. Until then, the always block will continue to wait at the
event control, and will not execute the assignment.


Icarus Verilog (and I suspect other Verilog simulators) makes a
positive effort to detect combinational "always" statements like
this and schedule them to start (and block themselves in the wait)
*before* initializations, so that combinational expressions come
out right when time-0 settles.

Perhaps, though this would not be compliant with the SV LRM :-(
 

Welcome to EDABoard.com

Sponsor

Back
Top