Guest thelonious

B/LED Wing: LED remains on, but only dimly

15 posts in this topic

Hi there,

I'm a complete newbiew and I know this is an easy question, so bear with me :)

I've created a very simply VHDL file that turns on LEDs using basic and/or gates. Here's an example:


architecture Behavioral of Button_LED is
process(PB)
begin
  LED(0) <= PB(0);
  LED(1) <= PB(1);
  LED(2) <= PB(0) and PB(1);
  LED(3) <= PB(0) or PB(1);
end Behavioral.

Everything works fine, but sometimes LED(3) will remain on, but dimly. I assume I need some sort of pull-down resistor, but after reading the migrated posts in this section, I see the board already does this for me. I do have rev 1.1. Any suggestions as to what might be causing this?

Thanks,

Kevin

Share this post


Link to post
Share on other sites

Kevin,

The Button/LED Wing does indeed already have pull-down resistors. If you download the Papilio/Arduino IDE and run the BPW5007_Button_LED_Wing example you should be able to verify that the Wing works properly.

Most likely what is happening is that your VHDL is not doing what you are expecting it to. When you synthesize the design look closely at the output. It will tell you what kind of primitives are created, it is most likely that the structure you are using to define you logic is inferring a latch or something that you did not intend. So first of all look at what it says, it may not show up as an error.

The next step is to start experimenting with different ways of implementing what you want. Basically you want an or gate with pushbuttons as inputs and the LED as the output. There are a couple different ways to do this in VHDL. Using a process is probably not the first way I would try. Why don't you try defining it as straight combinatorial code outside of a process:


architecture Behavioral of Button_LED is
  LED(0) <= PB(0);
  LED(1) <= PB(1);
  LED(2) <= PB(0) and PB(1);
  LED(3) <= PB(0) or PB(1);
end Behavioral.
--This would be outside the process

You can look at the Xilinx recommended way of doing something by looking at the "Language Templates" which is found under the Edit menu. I attached a screenshot of what it recommends for an or gate.

If this doesn't help I'll see if I can figure out what is happening later.

Share this post


Link to post
Share on other sites

Hey Jack,

Thanks. Of course, I can't recreate the issue now. I do notice even when the buttons are down, moving your finger a little is enough to break the connection. Perhaps it was an issue with the button that has worked itself out.

FWIW, the code (with proper syntax...bad copy/paste) I included in the original post was all I was using. I checked the RTL schematic and it was using an AND2 and OR2. The technology schematic had two simple LUTs.

Thanks for the correction on use of "process". I had started with the code in the ISE QuickStart, which uses a "process" for the counter. I had assumed stating an explicit dependency on changes in PB would allow for some optimization. Of course, that's not really needed here :)

Thanks again,

Kevin

Share this post


Link to post
Share on other sites

I'm a brand new Papilio One user (but long-time Spartan-IIE and Spartan-3A designer) and it's a wonderful little board.  I also got a Button/LED wing and I've seen misbehavior similar to Kevin's.  I found a simple work-around, so no action is needed, but I did want to share my experience.

 

Like Kevin, I wrote some simple logic to test the B/LED wing, in this case in Verilog:

 

// Demonstrate Papilio Button/LED wing.
module ButtonLED(PB1, PB2, PB3, PB4, LED1, LED2, LED3, LED4);
input    PB1, PB2, PB3, PB4;            // Push buttons, active-high.
output    LED1, LED2, LED3, LED4;        // LEDs, active-high.

    // Turn on LED1 unless PB1 and/or PB2 is pressed.
    assign LED1 = !(PB1 || PB2);
    // Turn on LED2 when both PB1 and PB2 are pressed.
    assign LED2 = PB1 && PB2;
    // Turn on LED3 if either PB3 xor PB2 is pressed.
    assign LED3 = PB3 ^ PB4;
    // Turn on LED4 if majority of PB2-PB4 are pressed.
    assign LED4 = PB2 && PB3 || (PB2 || PB3) && PB4;
endmodule
 

For the most part, this worked.  However, sometimes when I pressed both PB3 and PB4, and then released PB4, LED4 would stay on but be dimmer.  I tried plugging the wing in different positions, and some worked perfectly and some misbehaved in the same or in a different way.

 

I got out a very fast 'scope and took a look at PB4's signal, which should have been pulled down by a 47K resistor.  Well, instead it was oscillating about 350 MHz at around 1V, which was then causing the LED's drive signal to oscillate similarly.  Crazy!  To make an oscillator, you need an active driver.  Who's driving input PB4 if the button is released?

 

After thinking about it, I remembered that Spartan-3E inputs have hysteresis, so there's an active driver in there to implement the hysteresis.  So I think that it's the hysteresis circuit that's oscillating, but only under certain conditions so it's hard to reproduce and varies from pin to pin and chip to chip.

 

To narrow the problem down and perhaps work around it, I tried connecting the wing using jumpers and used active-low switches to ground for the PBs with pull-up resistors.  This fixed the problem immediately.

 

Then I modified the B/LED wing so that the buttons ground the PB1-4 signals, with the 47K resistors pulling up to 3.3V.  After changing the logic to use active-low PB1-4 inputs, this worked perfectly in all slots.

 

My conclusion is that the Spartan-3E hysteresis circuit does not like pull-down resistors and is much happier with pull-up resistors and active-low buttons that ground the inputs.  This is the usual way people connect buttons, so it's probably what was tested most thoroughly at Xilinx.

 

I tried to see if there was anything about this at the Xilinx forum and answer records, and found this one about an XCR3064XL: http://forums.xilinx.com/t5/General-Technical-Discussion/XCR3064XL-input-pin/m-p/374265

The customer didn't get an answer, but it does confirm that this sort of thing occurs.  Maybe the customer switched to using pull-ups instead of pull-downs and the problem went away as it did for me.

 

I'd be interested in whether others have seen anything similar with Spartan-3E.  I'm happy with my work-around, since I prefer active-low push-button inputs.  Another work-around might be to add a little capacitance to the button outputs to dampen the oscillation, but I didn't try it.

Share this post


Link to post
Share on other sites

Alvie asked: Can you try adding an internal PULLDOWN on the relevant lines of the UCF file ?

 

That was one of the first things I tried.  It changed which "Alow" pin was misbehaving.  Without the PULLDOWN, it was PB3 that was sticking on rather than PB4.  I also tried external pull-downs as low as 1K IIRC, and it still didn't stop the oscillation.  Probing with a cheap multimeter did stop the oscillation, probably because of relatively high capacitance.  I could only observe the signal with a 'scope probe (passive 500 MHz).

 

After thinking about this some more, I think there's an oscillation loop involving a 47K button pull-down and an LED.  My logic is very simple, so there's only one LUT between each PB input and each LED output.  The internal chip delay between I/O pads through the LUT and routing is probably only a few nanoseconds.  When I release the PB, the LED should go off but as it turns off it must couple somehow to the PB input hysteresis circuit, perhaps through an internal VCCO line with the logic itself is acting as an additional amplifier.  I suspect the problem only occurs because the delay loop is so short.  It's probably also dependent on the specific chip (process variation) and temperature (it's hotter today, so if I tried it today the electrons would probably move slower and prevent oscillation).

 

While the phenomenon is somewhat interesting, I don't have the inclination to investigate it further unless it comes back.  As I said above, I'm happy with my work-around and I far prefer pull-up resistors to pull-downs.  This is probably because I did so much TTL design at an impressionable age.  TTL inputs automatically pull-up, and TTL typically has 40 times higher pull-down current compared to pull-up current.  So pretty much all TTL designs used active-low buttons and active-low LEDs, which in those days took 10-20 mA to get a decent amount of light.  You kids get off my lawn!

Share this post


Link to post
Share on other sites

Alvie asked: What if you change the IOSTANDARD on the pins? Does it change anything?

 

I tried both LVTTL and LVCMOS33, with no change in behavior IIRC.

Share this post


Link to post
Share on other sites

I find this to be really odd, believe me.

 

Although you mention that hysteresis might be the root cause, I suspect it might be something else going on, like a small leakeage from the LED output into the button input, or a short in some outputs that cause the VCCIO to drop so much that signal inputs are no longer correct.

 

Is there any chance you getting me the routed netlist so I can take a look ?

Share this post


Link to post
Share on other sites

Alvie asked: Is there any chance you getting me the routed netlist so I can take a look?

 

I uploaded the source code and routed netlist (.ncd) file along .bit/bin files to the Downloads area.  Look for "BLEDall.zip" in Papilio Bit Files.

 

I converted my B/LED wing back to its original connections (buttons pull up to 3.3V with 47K pull-downs).  The BLEDall demo has six copies of the demo logic, one for each wing slot.  When I tried it today, only Alow is failing.  (The other day I was also seeing anomalies on Blow and Bhigh.)  The failure mode has changed slightly: now if I press PB3 alone both LED3 and LED4 come on, with LED4 not fully on.  When I press PB4 LED3 turns off (correctly) and LED4 turns on full.  I can also affect the behavior by touching the back of PB4.  There are a few more comments with the description at the Downloads area.

 

I'll be interested to hear whether you see anything on your board.  (Mine is Papilio One 250K.)  It's may be that the problem only affects a few boards, and that it depends on temperature, humidity, regulated voltage, and brand of bypass capacitor.

Share this post


Link to post
Share on other sites

Ok, the design looks correctly implemented. The flow is roughly like this:

 

PAD -> IBUF -> LUT -> OBUF -> PAD

 

For PB4x->LED4x, the pad-to-pad delay is about 6.5ns to 8ns. You are seeing 2.8ns, I don't think that it can be as fast, so the oscillation might indeed come from somewhere else.

 

If you loopback the LED output to the button input, so that it oscillates, what is the frequency you see ? Should be around 150MHz.

Share this post


Link to post
Share on other sites

Alive asked: If you loopback the LED output to the button input, so that it oscillates, what is the frequency you see ? Should be around 150MHz.

 

Here's what I'm getting today.  With the B/LED wing in slot Alow, PB3 is misbehaving -- about half the time if I press it alone both LED3 and LED4 come on, oscillating.  With a 1GHz active probe, I'm getting approx 370 MHz on LED3 (oscillates between 1.1V and 3.5V), LED4 (oscillates between 1.0V and 3.5V), and PB4 (oscillates between 0.1V and 1.3V).  With just PB3 pressed, LED3 should be on solid (it's PB3 XOR PB4), LED4 should be off (it's MAJ(PB2, PB3, PB4)), and PB4 should be pulled to GND through 47K resistor.

 

I also took a look at signal B15.  On that I'm getting 900 mV centered at 0V.  This is almost certainly crosstalk: the B15 wire runs alongside A1 for several inches.  In the current design there are no FPGA pullups or pulldowns, so B15 is floating and thus susceptible to crosstalk.

 

I tried your suggestion of looping LED3 to PB3.  If I push PB4 so that LED3 = !PB3, I get a solid square wave approx 87 MHz.  This is consistent with the digital delay estimate.

 

So where is the 370 MHz coming from?  At this point it looks most like crosstalk-enabled analog resonance.  While you are right at the digital delay is too long for 370 MHz, that delay assumes that all nodes in the delay path start out fully charged to VCC or fully discharged to GND.  It takes time for the each node in the path to reach the threshold voltage needed to start switching the next node.  In our case, I'm guessing that each node in the chain is oscillating near the threshold voltage so it doesn't take anywhere as long to propagate a small voltage change to the next node in the path.

 

I tried using stronger pull-downs for PB4.  The B/LED pull-down is 47K.  With a 4.7K additional pull-down, the problem improves.  With a 910 Ohm additional pull-down it goes away.

 

I also took a look at A2 (connected to LED3) both at the FPGA (pin 26), at the B/LED connector, and at the LED.  The oscillation amplitude increases in each case, which is consistent with its being pumped by crosstalk.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now