Accidental latch inference (due to value range?)

G

googler

Guest
I have a combinational 'always' block inside which I am assigning to
some signals. For some reason, some of the signal assignments are
inferring a latch. The 'always' block has a 'for' loop inside it which
repeats 8 times and inside this loop, the signals are assigned. The
code looks like below.

reg abcd1[7:0];
reg [3:0] wxyz1[7:0];
reg abcd2[7:0];
reg [3:0] wxyz2[7:0];
reg [11:0] ptr;
integer ii2;

always @(ptr or ..............)
begin
for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd1[(ptr+ii2)%8] = <some expression>;
wxyz1[(ptr+ii2)%8] = <some expression>;
end

for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd2[ii2] = <some expression>;
wxyz2[ii2] = <some expression>;
end
end

In the above code, the signals abcd1[0], abcd1[1],....,abcd1[7] and
wxyz1[0], wxyz1[1],.....,wxyz1[7] are inferring latches. These signals
are all assigned inside the first 'for' loop. However, the signals
inside the second 'for' loop are not inferring latch. From this
behavior, I understood that in case of the first 'for' loop it is
inferring latches because the synthesis tool expects all values of
'ptr' to be covered. (I think in this case it might be a limitation of
the tool, because the loop iterates 8 times, so all the 8 values of
the index are covered anyway)

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.
 
googler wrote:

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.
I would use a clocked block.

-- Mike Treseler
 
googler wrote:
On Jul 11, 9:15 am, Mike Treseler <mike_trese...@comcast.net> wrote:
googler wrote:
So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.
I would use a clocked block.

-- Mike Treseler

My intention is to write the code in such a way that no latches or
flops are synthesized. This is intended to be purely combinational
logic and not a clocked block.
That's fine, but adding rules to avoid latch synthesis is one downside
to asynch blocks.
Since all of my designs are synchronous,
I prefer to combine the processes and simplify my design rules.
If you are driving device pins with async outputs
this is not an option.

--- Mike Treseler
 
On Jul 11, 1:33 am, googler <pinaki_...@yahoo.com> wrote:
I have a combinational 'always' block inside which I am assigning to
some signals. For some reason, some of the signal assignments are
inferring a latch. The 'always' block has a 'for' loop inside it which
repeats 8 times and inside this loop, the signals are assigned. The
code looks like below.

reg abcd1[7:0];
reg [3:0] wxyz1[7:0];
reg abcd2[7:0];
reg [3:0] wxyz2[7:0];
reg [11:0] ptr;
integer ii2;

always @(ptr or ..............)
begin
for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd1[(ptr+ii2)%8] = <some expression>;
wxyz1[(ptr+ii2)%8] = <some expression>;
end

for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd2[ii2] = <some expression>;
wxyz2[ii2] = <some expression>;
end
end

In the above code, the signals abcd1[0], abcd1[1],....,abcd1[7] and
wxyz1[0], wxyz1[1],.....,wxyz1[7] are inferring latches. These signals
are all assigned inside the first 'for' loop. However, the signals
inside the second 'for' loop are not inferring latch. From this
behavior, I understood that in case of the first 'for' loop it is
inferring latches because the synthesis tool expects all values of
'ptr' to be covered. (I think in this case it might be a limitation of
the tool, because the loop iterates 8 times, so all the 8 values of
the index are covered anyway)

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.
Perhaps if you only use the low 3 bits of ptr in your expression?

abcd1[(ptr[2:0]+ii2)%8] = <some expression>;

Although I would think the modulo 8 would make that unnecessary. Did
you try always @* instead of the spelled-out sensitivity list?
 
On Thu, 10 Jul 2008 22:33:20 -0700 (PDT), googler
<pinaki_m77@yahoo.com> wrote:

I have a combinational 'always' block inside which I am assigning to
some signals. For some reason, some of the signal assignments are
inferring a latch. The 'always' block has a 'for' loop inside it which
repeats 8 times and inside this loop, the signals are assigned. The
code looks like below.

reg abcd1[7:0];
reg [3:0] wxyz1[7:0];
reg abcd2[7:0];
reg [3:0] wxyz2[7:0];
reg [11:0] ptr;
integer ii2;

always @(ptr or ..............)
begin
for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd1[(ptr+ii2)%8] = <some expression>;
wxyz1[(ptr+ii2)%8] = <some expression>;
end

for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd2[ii2] = <some expression>;
wxyz2[ii2] = <some expression>;
end
end

In the above code, the signals abcd1[0], abcd1[1],....,abcd1[7] and
wxyz1[0], wxyz1[1],.....,wxyz1[7] are inferring latches. These signals
are all assigned inside the first 'for' loop. However, the signals
inside the second 'for' loop are not inferring latch. From this
behavior, I understood that in case of the first 'for' loop it is
inferring latches because the synthesis tool expects all values of
'ptr' to be covered. (I think in this case it might be a limitation of
the tool, because the loop iterates 8 times, so all the 8 values of
the index are covered anyway)

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.
There are a couple of things you can try: First I agree that it maybe
an issue with the synthesizer because your index expression should
cover the range but the tool doesn't notice it. You can help it by
declaring a local 3 bit register for the index and assign the index
first then your variable ie:

begin: foo
reg [2:0] ix;
for ...
ix = (ptr+ii2)%8;
abcd1[ix] = ...
....
end

Another option is to move the index calculation to the for loop so
something like:

for (ii2 = ptr; ii2 < ptr; ii2 = (ii2 +1 )%8)
abdcd1[ii2] = ...

but you have to figure out how to write the loop expression to start
with ptr and stop at ptr-1, it's too early for me.

Hope this helps.
 
On Jul 11, 9:15 am, Mike Treseler <mike_trese...@comcast.net> wrote:
googler wrote:
So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.

I would use a clocked block.

   -- Mike Treseler
My intention is to write the code in such a way that no latches or
flops are synthesized. This is intended to be purely combinational
logic and not a clocked block.
 
On Jul 11, 8:33 am, googler <pinaki_...@yahoo.com> wrote:
I have a combinational 'always' block inside which I am assigning to
some signals. For some reason, some of the signal assignments are
inferring a latch. The 'always' block has a 'for' loop inside it which
repeats 8 times and inside this loop, the signals are assigned. The
code looks like below.

reg          abcd1[7:0];
reg [3:0]  wxyz1[7:0];
reg          abcd2[7:0];
reg [3:0]  wxyz2[7:0];
reg [11:0] ptr;
integer ii2;

always @(ptr or ..............)
begin
   for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
   begin
         abcd1[(ptr+ii2)%8] = <some expression>;
         wxyz1[(ptr+ii2)%8] = <some expression>;
   end

   for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
   begin
         abcd2[ii2] = <some expression>;
         wxyz2[ii2] = <some expression>;
   end
end

In the above code, the signals abcd1[0], abcd1[1],....,abcd1[7] and
wxyz1[0], wxyz1[1],.....,wxyz1[7] are inferring latches. These signals
are all assigned inside the first 'for' loop. However, the signals
inside the second 'for' loop are not inferring latch. From this
behavior, I understood that in case of the first 'for' loop it is
inferring latches because the synthesis tool expects all values of
'ptr' to be covered. (I think in this case it might be a limitation of
the tool, because the loop iterates 8 times, so all the 8 values of
the index are covered anyway)

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.
is all the variables in your <some expression> covered in the
sensitivity list? if not, this would definitly cause a latch. as
gabor said, have you tried using "always @*"?
other then that, I would try to use simpler statements, like using the
exact bits needed, or, if you can, state the logic without the for (if
it's only 8)
Gil.
 
On Jul 12, 10:01 am, GilGr <gil.greenst...@gmail.com> wrote:
On Jul 11, 8:33 am, googler <pinaki_...@yahoo.com> wrote:



I have a combinational 'always' block inside which I am assigning to
some signals. For some reason, some of the signal assignments are
inferring a latch. The 'always' block has a 'for' loop inside it which
repeats 8 times and inside this loop, the signals are assigned. The
code looks like below.

reg abcd1[7:0];
reg [3:0] wxyz1[7:0];
reg abcd2[7:0];
reg [3:0] wxyz2[7:0];
reg [11:0] ptr;
integer ii2;

always @(ptr or ..............)
begin
for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd1[(ptr+ii2)%8] = <some expression>;
wxyz1[(ptr+ii2)%8] = <some expression>;
end

for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd2[ii2] = <some expression>;
wxyz2[ii2] = <some expression>;
end
end

In the above code, the signals abcd1[0], abcd1[1],....,abcd1[7] and
wxyz1[0], wxyz1[1],.....,wxyz1[7] are inferring latches. These signals
are all assigned inside the first 'for' loop. However, the signals
inside the second 'for' loop are not inferring latch. From this
behavior, I understood that in case of the first 'for' loop it is
inferring latches because the synthesis tool expects all values of
'ptr' to be covered. (I think in this case it might be a limitation of
the tool, because the loop iterates 8 times, so all the 8 values of
the index are covered anyway)

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.

is all the variables in your <some expression> covered in the
sensitivity list? if not, this would definitly cause a latch. as
gabor said, have you tried using "always @*"?
other then that, I would try to use simpler statements, like using the
exact bits needed, or, if you can, state the logic without the for (if
it's only 8)
Gil.
You have to think how the synthesis tool would recognize the fact that
all possible values of ptr will result in an expression being assigned
to all of your array elements. It is very likely that the modulus
operator is the blocking point in the tool's ability to do this.

It would be interesting to see what the synthesis would generate
(extra logic rather than latches) if you added an initialization
loop at the top of the always block like:

always @(ptr or ..............)
begin
for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd1[ii2] = 0;
wxyz1[ii2] = 0;
end

for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd1[(ptr+ii2)%8] = <some expression>;
wxyz1[(ptr+ii2)%8] = <some expression>;
end

for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd2[ii2] = <some expression>;
wxyz2[ii2] = <some expression>;
end
end

Regards,
Gabor
 
On Jul 11, 10:18 am, Muzaffer Kal <k...@dspia.com> wrote:
On Thu, 10 Jul 2008 22:33:20 -0700 (PDT), googler





pinaki_...@yahoo.com> wrote:
I have a combinational 'always' block inside which I am assigning to
some signals. For some reason, some of the signal assignments are
inferring a latch. The 'always' block has a 'for' loop inside it which
repeats 8 times and inside this loop, the signals are assigned. The
code looks like below.

reg          abcd1[7:0];
reg [3:0]  wxyz1[7:0];
reg          abcd2[7:0];
reg [3:0]  wxyz2[7:0];
reg [11:0] ptr;
integer ii2;

always @(ptr or ..............)
begin
  for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
  begin
        abcd1[(ptr+ii2)%8] = <some expression>;
        wxyz1[(ptr+ii2)%8] = <some expression>;
  end

  for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
  begin
        abcd2[ii2] = <some expression>;
        wxyz2[ii2] = <some expression>;
  end
end

In the above code, the signals abcd1[0], abcd1[1],....,abcd1[7] and
wxyz1[0], wxyz1[1],.....,wxyz1[7] are inferring latches. These signals
are all assigned inside the first 'for' loop. However, the signals
inside the second 'for' loop are not inferring latch. From this
behavior, I understood that in case of the first 'for' loop it is
inferring latches because the synthesis tool expects all values of
'ptr' to be covered. (I think in this case it might be a limitation of
the tool, because the loop iterates 8 times, so all the 8 values of
the index are covered anyway)

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.

There are a couple of things you can try: First I agree that it maybe
an issue with the synthesizer because your index expression should
cover the range but the tool doesn't notice it.
I see this problem both on Magma synthesis and on running Atrenta
Spyglass RTL checking tool. While this may not be the most
straightforward case for the tools to detect, I think it's still a bug/
limitation of the tools.

You can help it by
declaring a local 3 bit register for the index and assign the index
first then your variable ie:

begin: foo
reg [2:0] ix;
for ...
        ix = (ptr+ii2)%8;
        abcd1[ix] = ...
...
end
Thanks for the suggestions. I tried this, but it didn't work :(

Another option is to move the index calculation to the for loop so
something like:

for (ii2 = ptr; ii2 < ptr; ii2 = (ii2 +1 )%8)
        abdcd1[ii2] = ...

Didn't try this out, but have a feeling that it would result in the
same.

I also tried what gabor suggested, that is, "abcd1[(ptr[2:0]+ii2)%8] <some expression>;". Didn't help either.

I finally solved this problem by having another for loop before the
existing one where I initialize all the array elements to 0.

for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
begin
abcd1[ii2] = 1'b0;
wxyz1[ii2] = 4'b0;
end
 
On Jul 12, 9:30 am, gabor <ga...@alacron.com> wrote:
On Jul 12, 10:01 am, GilGr <gil.greenst...@gmail.com> wrote:

snip

You have to think how the synthesis tool would recognize the fact that
all possible values of ptr will result in an expression being assigned
to all of your array elements.  It is very likely that the modulus
operator is the blocking point in the tool's ability to do this.

It would be interesting to see what the synthesis would generate
(extra logic rather than latches) if you added an initialization
loop at the top of the always block like:

always @(ptr or ..............)
begin
   for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
   begin
         abcd1[ii2] = 0;
         wxyz1[ii2] = 0;
   end

   for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
   begin
         abcd1[(ptr+ii2)%8] = <some expression>;
         wxyz1[(ptr+ii2)%8] = <some expression>;
   end

   for (ii2 = 0; ii2 < 8; ii2 = ii2+1)
   begin
         abcd2[ii2] = <some expression>;
         wxyz2[ii2] = <some expression>;
   end
end

Regards,
Gabor
Yes exactly, that's how I solved the problem. Just posted it moments
before I saw your post. Thanks.
 
On Jul 12, 9:01 am, GilGr <gil.greenst...@gmail.com> wrote:
On Jul 11, 8:33 am, googler <pinaki_...@yahoo.com> wrote:





I have a combinational 'always' block inside which I am assigning to
some signals. For some reason, some of the signal assignments are
inferring a latch. The 'always' block has a 'for' loop inside it which
repeats 8 times and inside this loop, the signals are assigned. The
code looks like below.

snip

So my question is, how to write this code so that the first 'for' loop
does not infer any latch? Thanks.

is all the variables in your <some expression> covered in the
sensitivity list?  if not, this would definitly cause a latch. as
gabor said, have you tried using "always @*"?
Yes, all variables are covered in sensitivity list.

other then that, I would try to use simpler statements, like using the
exact bits needed, or, if you can, state the logic without the for (if
it's only 8)
Gil
I was thinking about unrolling the loop too if nothing else worked
(finally I solved it by initializing the array elements to 0's in a
separate 'for' loop just before the existing 'for' loop). I guess this
would have fixed the problem.
 

Welcome to EDABoard.com

Sponsor

Back
Top