ISE bug?

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:

=((A1*A4)@A2); bel .

when it doesn't work I get:

=((~A2*(A1*A4))+(A2*(~A1+~A4))); bel .

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

Reply to
Andrew Holme
Loading thread data ...

(snip)

Looks the same to me. Though carry logic is important in counters, and if you get that wrong it won't work.

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

Reply to
glen herrmannsfeldt

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.

Reply to
Andrew Holme

This statement doesn't make sense. For a synchonous load, the counter reloads on the counter clock.

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

(snip)

The equations aren't the same with that swap.

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.

Better to synchronize the enable to the counter clock domain.

-- glen

Reply to
glen herrmannsfeldt

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.

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

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

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.

Reply to
Andrew Holme

(snip)

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

Reply to
glen herrmannsfeldt

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...
 Click to see the full signature
Reply to
Nico Coesel

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

Reply to
Bob Perlman

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

Reply to
Andrew Holme

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.