ISE bug?

A

Andrew Holme

Guest
I'm still using ISE 8.2i. Yes, I know. But it's served me well and I live
by the "if it works don't upgrade it principle."

"Served me well" until now that is. I may have found a bug. My FPGA works
sometimes. Then I make certain innocent, harmless, neutral changes in an
un-related area ... things stop working. Not an uncommon experience for
FPGA engineers, I know.

I've possibly traced it to a high speed (200 MHz) counter which is reloaded
using data from another clock domain . That data is stable when the counter
reloads; but the point where it changes relative to the counter clock is
uncontrolled.

I've checked the counter implementation using FPGA editor and noticed
something curious about the LUT equations. When it works I get:

<F>=((A1*A4)@A2); bel <vco_fa[0]/Mxor_d_Result1>.

when it doesn't work I get:

<F>=((~A2*(A1*A4))+(A2*(~A1+~A4))); bel <vco_fa[0]/Mxor_d_Result1>.

for the same LUT, which is bit 0 of the counter.

A1 is the reload control
A2 is counter Q[0]
A4 is the load input from another clock domain.

The above two boolean expressions are equivalent; but why does FPGA Editor
dump them in different formats and how do I verify what is actually in the
LUT?

I'm wondering if a glitch is coming through the LUT when A4 changes

TIA
 
"Andrew Holme" <ah@nospam.com> wrote in message
news:UPf0q.40$Ei6.0@newsfe15.ams2...
I'm still using ISE 8.2i. Yes, I know. But it's served me well and I
live by the "if it works don't upgrade it principle."

"Served me well" until now that is. I may have found a bug. My FPGA
works sometimes. Then I make certain innocent, harmless, neutral changes
in an un-related area ... things stop working. Not an uncommon experience
for FPGA engineers, I know.

I've possibly traced it to a high speed (200 MHz) counter which is
reloaded using data from another clock domain . That data is stable when
the counter reloads; but the point where it changes relative to the
counter clock is uncontrolled.

I've checked the counter implementation using FPGA editor and noticed
something curious about the LUT equations. When it works I get:

F>=((A1*A4)@A2); bel <vco_fa[0]/Mxor_d_Result1>.

when it doesn't work I get:

F>=((~A2*(A1*A4))+(A2*(~A1+~A4))); bel <vco_fa[0]/Mxor_d_Result1>.

for the same LUT, which is bit 0 of the counter.

A1 is the reload control
A2 is counter Q[0]
A4 is the load input from another clock domain.

The above two boolean expressions are equivalent; but why does FPGA Editor
dump them in different formats and how do I verify what is actually in the
LUT?

I'm wondering if a glitch is coming through the LUT when A4 changes

TIA
OK, I checked the technology viewer. The LUT3 inputs are connected in
different orders.

Working FPGA:
LUT3_6C
i0 = reload control
i1 = from q output
i2 = reload data from another domain

Broken FPGA:
LUT3_6A
i0 = from q output
i1 = reload control
i2 = reload data from another domain

Apart from swapping i0 and i1, the LUT equations are identical.

I thought LUT's don't glitch when their inputs change; but I'm wondering if
they can in this scenario.

It sounds like I need to instantiate this counter entirely from primitives.
 
"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:j1s740$nn7$1@speranza.aioe.org...
Andrew Holme <ah@nospam.com> wrote:

I've possibly traced it to a high speed (200 MHz) counter which is
reloaded using data from another clock domain . That data is stable
when
the counter reloads; but the point where it changes relative to the
counter clock is uncontrolled.

This statement doesn't make sense. For a synchonous load, the
counter reloads on the counter clock.
Yes, the reload control is synchronous with the counters clock. The reload
data is not but it should be stable for several cycles before and after the
reload. The eaxacrt instance at which it later changes could occur anywhere
within the counter clock cycle.

I've checked the counter implementation using FPGA editor and noticed
something curious about the LUT equations. When it works I get:

F>=((A1*A4)@A2); bel <vco_fa[0]/Mxor_d_Result1>.

This doesn't look right for a counter with a load enable.
It always adds the counter; but the counter contents are zero in the reload
cycle.

(snip)
OK, I checked the technology viewer. The LUT3 inputs are connected in
different orders.

Working FPGA:
LUT3_6C
i0 = reload control
i1 = from q output
i2 = reload data from another domain

Broken FPGA:
LUT3_6A
i0 = from q output
i1 = reload control
i2 = reload data from another domain

Apart from swapping i0 and i1, the LUT equations are identical.

The equations aren't the same with that swap.
Why do you say that? They are by my reckoning.

I thought LUT's don't glitch when their inputs change; but I'm
wondering if they can in this scenario.

They don't glitch when going to a state with the same output value.
That doesn't always happen with a load enable on a counter.

It sounds like I need to instantiate this counter entirely
from primitives.

Better to synchronize the enable to the counter clock domain.

-- glen
Thanks for the suggestion; but, as I said, it is.

I tried instatntiating the LUT3 primitive and this did indeed make the "bad"
FPGA slice look exactly the same as the "good" FPGA. Unfortunately, the
"bad" FPGA still doesn't work :-(

I will attempt your earlier suggestion of re-timing the reload data to the
counter clock.
 
Andrew Holme <ah@nospam.com> wrote:

(snip)
I've possibly traced it to a high speed (200 MHz) counter which is reloaded
using data from another clock domain . That data is stable when the counter
reloads; but the point where it changes relative to the counter clock is
uncontrolled.

I've checked the counter implementation using FPGA editor and noticed
something curious about the LUT equations. When it works I get:

F>=((A1*A4)@A2); bel <vco_fa[0]/Mxor_d_Result1>.

when it doesn't work I get:

F>=((~A2*(A1*A4))+(A2*(~A1+~A4))); bel <vco_fa[0]/Mxor_d_Result1>.
Looks the same to me. Though carry logic is important in
counters, and if you get that wrong it won't work.

for the same LUT, which is bit 0 of the counter.

A1 is the reload control
A2 is counter Q[0]
A4 is the load input from another clock domain.

The above two boolean expressions are equivalent; but why does FPGA Editor
dump them in different formats and how do I verify what is actually in the
LUT?

I'm wondering if a glitch is coming through the LUT when A4 changes
Tradition would be to use a Gray code counter when crossing clock
domains, such that it either gets the count before or after.

But you aren't actually sending a count across a clock domain.

Seems to me that the failure mode would be some bits get the load
value and some don't. Can you bring load into the same clock
domain, and then use it? That might require it to come some number
of clocks earlier.

-- glen
 
Andrew Holme <ah@nospam.com> wrote:

I've possibly traced it to a high speed (200 MHz) counter which is
reloaded using data from another clock domain . That data is stable when
the counter reloads; but the point where it changes relative to the
counter clock is uncontrolled.
This statement doesn't make sense. For a synchonous load, the
counter reloads on the counter clock.

I've checked the counter implementation using FPGA editor and noticed
something curious about the LUT equations. When it works I get:

F>=((A1*A4)@A2); bel <vco_fa[0]/Mxor_d_Result1>.
This doesn't look right for a counter with a load enable.

(snip)
OK, I checked the technology viewer. The LUT3 inputs are connected in
different orders.

Working FPGA:
LUT3_6C
i0 = reload control
i1 = from q output
i2 = reload data from another domain

Broken FPGA:
LUT3_6A
i0 = from q output
i1 = reload control
i2 = reload data from another domain

Apart from swapping i0 and i1, the LUT equations are identical.
The equations aren't the same with that swap.

I thought LUT's don't glitch when their inputs change; but I'm
wondering if they can in this scenario.
They don't glitch when going to a state with the same output value.
That doesn't always happen with a load enable on a counter.

It sounds like I need to instantiate this counter entirely
from primitives.
Better to synchronize the enable to the counter clock domain.

-- glen
 
Andrew Holme <ah@nospam.com> wrote:

(snip)
I've checked the counter implementation using FPGA editor and noticed
something curious about the LUT equations. When it works I get:

F>=((A1*A4)@A2); bel <vco_fa[0]/Mxor_d_Result1>.

This doesn't look right for a counter with a load enable.

It always adds the counter; but the counter contents are zero
in the reload cycle.

(snip)
OK, I checked the technology viewer. The LUT3 inputs are connected in
different orders.

Working FPGA:
LUT3_6C
i0 = reload control
i1 = from q output
i2 = reload data from another domain

Broken FPGA:
LUT3_6A
i0 = from q output
i1 = reload control
i2 = reload data from another domain

Apart from swapping i0 and i1, the LUT equations are identical.

The equations aren't the same with that swap.

Why do you say that? They are by my reckoning.

They are symmetric on exchange of i0 and i2, which go to A1 and A4.
It seems to have been snipped, but that is the way I read the post.

-- glen
 
"Andrew Holme" <ah@nospam.com> wrote:

"Andrew Holme" <ah@nospam.com> wrote in message
news:UPf0q.40$Ei6.0@newsfe15.ams2...
I'm still using ISE 8.2i. Yes, I know. But it's served me well and I
live by the "if it works don't upgrade it principle."

"Served me well" until now that is. I may have found a bug. My FPGA
works sometimes. Then I make certain innocent, harmless, neutral changes
in an un-related area ... things stop working. Not an uncommon experience
for FPGA engineers, I know.


OK, I checked the technology viewer. The LUT3 inputs are connected in
different orders.

Working FPGA:
LUT3_6C
i0 = reload control
i1 = from q output
i2 = reload data from another domain

Broken FPGA:
LUT3_6A
i0 = from q output
i1 = reload control
i2 = reload data from another domain

Apart from swapping i0 and i1, the LUT equations are identical.

I thought LUT's don't glitch when their inputs change; but I'm wondering if
they can in this scenario.

It sounds like I need to instantiate this counter entirely from primitives.
No, this is a clock domain crossing problem. Be sure to put
constraints on the signals which go from one domain to the other.

Typically one signal should indicate there is 'new data'. Due to
sampling this signal is usually delayed by 1 destination clock cycle.
The 'new data' should be constrained to go from source domain to
destination domain within one period of the destination clock.

--
Failure does not prove something is impossible, failure simply
indicates you are not using the right tools...
nico@nctdevpuntnl (punt=.)
--------------------------------------------------------------
 
I found it!

It wasn't a LUT glitch. There are no LUT glitches. I take it back.

It wasn't a clock domain crossing problem. The loaded data is stable before
during and after the reload.

It's a synthesis bug in ISE8.2i which is most easily seen in "View
Technology Schematic" for this:

module Test (
input clk,
output [7:0] out1,
output [7:0] out2
);

function [7:0] bcd2bin;
input [8:0] bcd;
begin
bcd2bin = 8'd100*bcd[8] + 8'd10*bcd[7:4] + bcd[3:0]; // 000 ... 199
end
endfunction

wire [8:0] in1;
reg [8:0] in2;

assign in1 = 9'h155;

always @ (posedge clk) in2 <= 9'h155;

assign out1 = bcd2bin(in1);
assign out2 = bcd2bin(in2);

endmodule


out1 is 8'b00011011
out2 is 8'b10011011
 
Before I repeat some of the advice that others have given, let's
review some fundamentals:

1) Combinatorial logic is glitchy. Yes, in some cases you can
eliminate
glitches with careful design and a thorough knowledge of the
underlying
technology. But unless you've painted yourself into a corner or are
doing
something incredibly clever, I don't recommend the hand tweaking of
low-level
combinatorics.

2) For synchronous design, we don't care about the logic glitches.
Provided
we've met setup and hold requirements, logic levels will settle out by
the time
we're ready to sample them. (In fact, I suspect that many logic
designers
aren't aware of combinatorial glitches because they've been doing
synchronous
design, and are thus blissfully unaware of the glitches that are
generated and
ignored in their circuits. Anyone who's tried to clock a flip- flop
with the
terminal count of a 74161 has learned the lesson, or gone into another
line of
work. Yes, I'm old. Deal with it.)

3) Transferring data or control between mutually-asynchronous
subsystems is a
whole other matter. In the situation we're discussing here, a LUT
glitch can
occur just as the counter is updating, regardless of whether the load
signal is
active.

The best approach, as has been suggested by others, is to put a
register between
the incoming load value and the counter, and clock that register with
the
counter clock. One other thing: be sure to create a time spec between
the
register and the counter, and set the spec as low as possible, to give
the
register plenty of time to come out of a metastable state before the
counter
clocks.

Bob Perlman
Cambrian Design Works
 

Welcome to EDABoard.com

Sponsor

Back
Top