Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

A very simple problem about FPGA I/O Status

Hi All,

Thanks in advance for your time and possible efforts here.

What I want to do is to monitor a push button. When it is pushed, its related signal changes from H to L, and light on a LED. After the LED is ON for certain period, turn it OFF.

The code is very short, which is listed here:

---------------------------------------------------------------------------------

module PushButtomDetect( input Start, /* Start is the signal of Push Button */

input CLK, /* 50Mhz */

output reg Start_Detect_LED); /* connected to drive LED */reg [3:0] Start_Monitor;

reg Start_Flag = 0;

reg [27:0] DelayCounter;

always @(posedge CLK)

begin

Start_Monitor[0] <= Start;

Start_Monitor[3:1] <= Start_Monitor[2:0];

Start_Flag <= Start_Monitor[3]&(~Start_Monitor[2]); /* Monitor H to L Transition */

if(Start_Flag == 1)

Start_Detect_LED <= 1; /* LED is ON when Start has a Negative edge */

if(Start_Detect_LED == 1) /* LED is turned OFF when it has been ON for 1 second */

begin

DelayCounter <= DelayCounter + 1;

if(DelayCounter == 28'b0011_0010_0000_0000_0000_0000_0000)

begin

DelayCounter <= 28'b0000_0000_0000_0000_0000_0000_0000;

Start_Detect_LED <= 0;

end

end

end

endmodule

------------------------------------------------------------------------------------------------

start is the signal from push button sw0, which is pulled up by on-board resistor.

for this code, everything works as expected. When [/B]I programmed the code into chip, the LED is OFF, [/B]and after I push the button, LED is ON, after 1 second, it is OFF. Fine!

However, if I commented the paragraph used to turn off the LED, which is like:

-------------------------------------------------------------------------------------------------------

// if(Start_Detect_LED == 1) /* LED is turned OFF when it has been ON for 1 second */

// begin

// DelayCounter <= DelayCounter + 1;

// if(DelayCounter == 28'b0011_0010_0000_0000_0000_0000_0000)

// begin

// DelayCounter <= 28'b0000_0000_0000_0000_0000_0000_0000;

// Start_Detect_LED <= 0;

// end

// end

------------------------------------------------------------------------------------------------------

something strange to me happens. when i programmed the code into chip, the led is on immediately after the program process finishes, without push on the button.

I know the status of FPGA would be uncertain during startup. But what is the exact reason here?

Thanks~~

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The reason would be how the logic is optimized.

    In your previous design with the timer, the logic may be high or low or unknown. So the design happens to get initialized as zero, and it works as you expect it to.

    When you change the design so your timer is removed you are also removing the only thing that can set the LED to off. So all the start logic gets optimized out because your only possible states on your LED are on or unknown. Since it doesn't care about the "Unknown" state in the optimization, it will just end up tying the LED to on.

    Now although your designed worked, in your case in practice and simulation having uninitialized counters and outputs can cause problems.

    I would recommend having a reset in the design, or at the very least having the counter start with the push button at a known count then count down to zero.

    If you tried to simulate this design, all you would get at the output would be X's because the initial state of your counter is unknown, so adding 1 to an unknown is still an unknown.

    How this would manifest itself in an ASIC, is the first time the button was pushed your delay would not be random.

    In an FPGA it would most likely be consistent but it may that the counter gets initialized as all zero's or all one's as the devices is programmed.

    Pete
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi anakha,

    Your opinion on optimization is correct. I tried to initialize as:

    reg Start_Detect = 0;

    assign Start_Detect_LED = Start_Detect;

    always @(posedge CLK)

    begin

    Start_Monitor[0] <= Start;

    Start_Monitor[3:1] <= Start_Monitor[2:0];

    Start_Flag <= (Start_Monitor[3]&(~Start_Monitor[2]));

    if(Start_Flag == 1)

    Start_Detect <= 1;

    end

    This code worked as expected. So it seems that uninitialized register would cause this kind of 'Optimization' problem.

    But this is pretty wired to me. Why the Optimization (done by Quartus) is designed like this? Can I bypass this kind of optimization?

    Thanks~~
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You can not disable this reduction, you can tell it to optimize the design for speed or area.

    However in this case, the reduction would still be the same. Since you "Don't Care" what the initial condition is, and you can ONLY have a set condition of 1, it will reduce the logic to a 1 all the time.

    The first stage of synthesis is to map all the logic then reduce it as much as possible using boolean logic reduction rules. Once that is done, it will then look at timing and area constraints and remap the logic a second time.

    Pete