[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: gEDA-user: HELP with Icarus Verilog, 0.7!



Hi,

"Samuel A. Falvo II" wrote:

> On Tuesday 06 April 2004 01:21 pm, Mike Jarabek wrote:
> > Not quite true, the always block is only evaluated when something on
> > the sensitivity list changes.  In this case, that only happens when
> > RST changes.  When your clock changes the other always block will
> > fire, depending on the state of the _E signals, your register will be
> > overwritten.
>
> But it must be true.  If RST changes state, then any continuous
> assignment using RST as an input will also be re-evaluated at that time.
> So regardless of what happens to the clock, when the RST is asserted,
> all the continuous assignments for *_E will be re-evaluated, and will
> become negated.

Try out the following sequence of events as a thought experiment, using the
following Verilog code with the same structure as your code: (a is
analogous to your register, b is the `clock', c is the enable signal, and d
is the reset signal)

--------------------------
module test;
   reg [1:0] a;
   reg       b,c,d;

   always @(posedge b) begin
      if(c) a <= 2'h1;
   end

   always @(d) begin
      if(d) a<= 2'h2;
   end

   initial begin
      $monitor($time," ",a,b,c,d);
   end

   initial begin
      b = 0; c = 0; d=0;
      #1;
      b = 1; c = 0; d=0;
      #1;
      b = 0; c = 0; d=0;
      #1;
      b = 1; c = 0; d=1;  /* assert the reset here */
      #1;
      b = 0; c = 0; d=0;
      #1;
      b = 1; c = 1; d=0;  /* load the value here */
      #1;
      b = 0; c = 0; d=0;
      #1;
      b = 1; c = 0; d=0;
      #1;
      b = 0; c = 0; d=1;  /* reset the value here */
      #1;
      b = 1; c = 1; d=1;  /* Watch the value change while reset is asserted
*/
      #1;
      b = 0; c = 0; d=1;  /* but it does not change here */
      #1;
      b = 1; c = 0; d=0;
      #1;
      b = 0; c = 0; d=0;
      #1;
      b = 1; c = 1; d=1;  /* The results here are simulator dependent */
   end
endmodule
---------------------------
[mike@laptop tmp]$ iverilog test.v
[mike@laptop tmp]$ ./a.out
                   0 x000
                   1 x100
                   2 x000
                   3 2101
                   4 2000
                   5 1110
                   6 1000
                   7 1100
                   8 2001
                   9 1111
                  10 1001
                  11 1100
                  12 1000
                  13 2111
[mike@laptop tmp]$ iverilog -V
Icarus Verilog version 0.7
Copyright 1998-2002 Stephen Williams
$Name: s20030904 $
[mike@laptop tmp]$
-----------------------------
Note the second `reset' at time 8, this puts the reset value back into the
`reg' variable, but also note that at time 9, the value `1' gets loaded
into the register, even though d is still asserted.  This happens because
Verilog treats a register a lot like a (global) variable in a proceedural
programming language.  At time 13 I created a race condition with the clock
and the reset line changing at the same time, Icarus causes the second
block to fire last in this case, but Verilog does not guarentee that,
equally well the first block could have fired second, leaving `1' in the a
register.  This is a classic race condition that can be avoided by never
allowing a `reg' or `integer' to appear on the left hand side of any
blocking or non-blocking assignement in more than one always block.
Verilog does guarentee that the last assigment in a sequential block is
what actually winds up in the register at the end of the time step.  You
can use this to your advantage if you want some kind of implied priority
scheme by conditionally assigning values to the register in increasing
priority.  That is, with the highest priority items coming last in the
always block.  You can override this priority with special synthesis
commands if you know that the input conditions will be mutually exclusive.

>
>
> Oh, wait, the _E signals in the example I posted are raw inputs.  I see
> what you're getting at.  I forgot that I changed this in a subsequent
> version of the receiver (the one that uses a Wishbone interface, and
> does its own, internal address decoding), where the _E signal is now
> generated internally, and is qualified against both CLK_I and RES_I.

The same condition is still there, it has just moved to the address inputs
instead of the enable signals.  It's something of a bad idea to use the
clock to qualify signals, especially if this is a synchronous design
anyhow.

<SNIP>
Mike Jarabek