+ Post New Thread
Results 1 to 11 of 11
  1. #1
    Member level 3
    Points: 1,349, Level: 8
    bremenpl's Avatar
    Join Date
    Jan 2013
    Posts
    61
    Helped
    0 / 0
    Points
    1,349
    Level
    8

    Initial value depending on the input

    Hello there,
    I am designing a simple debounce mechanism in VHDL. I have the following problem. An internal counter (a variable) should be initially set to 0 or some value (ie. 100), depending on either the input is high or low at power up. I have no idea how to implement this. Is it even possible? At the moment my internal "key" state is initialized with input value, but for some reason this doesnt work. The first transition always fails (no debounce). I am using additional boolean generic's in order to enable the debounce for either up or low transitions.

    Code:
    -- Libraries -------------------------------------------------------------------
    
    --! Main library
    library ieee;				
    	--! std logic components		
    	use ieee.std_logic_1164.all;
    
    -- Entity ----------------------------------------------------------------------
    
    --! bouncer signals
    entity entity_debounce is
    	generic
    	(
    		--! Stores the maximum hysteresis value. 
    		max				: 	natural;
    		
    		--! Disables the up counting hysteresis when true
    		hystup_dis		:	boolean;
    		
    		--! Disables the down counting hysteresis when true
    		hystdown_dis	:	boolean
    	);
    
    	port 
    	( 	
    		--! Clock signal. Rising edge triggers the counter.
    		clk 	: in 	std_logic;	
    		
    		--! Input signal that needs debouncing
    		input 	: in 	std_logic;	
    		
    		--! clean, debounced output
    		output	: out 	std_logic 	
    	);
    
    end entity_debounce;
    
    -- Architecture ----------------------------------------------------------------
    
    --! Debounce hysteresis mechanism implementation
    architecture arch_debounce of entity_debounce is
    
    	--! internal key memory state
    	signal key		: std_logic := input;	
    	
    begin
    	
    	process_debounce : process(clk)
    		
    		--! Hysteresis counter
    		variable cnt : natural := 0;
    		
    		begin
    			if (rising_edge(clk)) then
    				if (input = '1') then
    					if ((cnt < max) and (hystup_dis = false)) then
    						cnt := cnt + 1;
    					elsif (key = '0') then
    						key <= '1';
    						cnt := max;
    					end if;
    				else 
    					if ((cnt > 0) and (hystdown_dis = false)) then
    						cnt := cnt - 1;
    					elsif (key = '1') then
    						key <= '0';
    						cnt := 0;
    					end if;
    				end if;
    			end if;
    	end process;
    	
    	output <= key;
    
    end arch_debounce;
    .
    .
    .

    In the top vhd file:

    Code:
    	--! Debouncer instance 20 ms hysteresis debounce time
    	debounce_ledbtn20ms : entity_debounce
    		generic map 
    		(
    			max => 656,
    			hystup_dis => true,
    			hystdown_dis => false
    		)
    	
    		port map
    		(
    			clk => clk_32k,
    			input => pin_ledbtn,
    			output => pins_led(0)
    		);
    On the scope one can see that 1st transition is not correct, since falling edge should have debounce added (hystdown_dis => false). There should never be debounce added on rising edges and that is OK (hystup_dis => true).

    Click image for larger version. 

Name:	bounce.png 
Views:	2 
Size:	85.1 KB 
ID:	149945


    I would appreciate all help.
    Last edited by bremenpl; 8th November 2018 at 09:05.

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 249,046, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,337
    Helped
    13177 / 13177
    Points
    249,046
    Level
    100

    Re: Initial value depending on the input

    An initial value is either synthesized as constant or power-on-reset value, depending on the logic, in your case the latter.

    POR value can't depend on input, instead you'll need an explicit reset that stores the initial value. Simple, straightforward.

    You should consider that some logic families don't support asynchronous set function and need to emulate it by a logic loop latch, e.g. all newer Intel FPGA. As a drawback, the POR value of this latch will be undetermined.



  3. #3
    Member level 3
    Points: 1,349, Level: 8
    bremenpl's Avatar
    Join Date
    Jan 2013
    Posts
    61
    Helped
    0 / 0
    Points
    1,349
    Level
    8

    Re: Initial value depending on the input

    Hello, thank you for answer.

    you'll need an explicit reset that stores the initial value. Simple, straightforward.
    I tried doing just that- it did not help as well. I think in my situation (MachXO2 from Lattice) it is somewhat not possible to initialize the values this way. For example, when I created a separate bolean variable that is initialy false, and then in the behavioral code I check either it is false and set it to true forever, the synthesizer gave me a warning that my variable will always be true. So, its like it was never initialized with false. Also, the code didnt work so this had to be the case...



    •   AltAdvertisment

        
       

  4. #4
    Super Moderator
    Points: 249,046, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,337
    Helped
    13177 / 13177
    Points
    249,046
    Level
    100

    Re: Initial value depending on the input

    You didn't show what you have tried. As said, the posted code, using an input value as initializer doesn't work.

    Reading an input during reset and initializing a counter respectively should work. I have coded similar hardware more than once.



  5. #5
    Member level 3
    Points: 1,349, Level: 8
    bremenpl's Avatar
    Join Date
    Jan 2013
    Posts
    61
    Helped
    0 / 0
    Points
    1,349
    Level
    8

    Re: Initial value depending on the input

    Quote Originally Posted by FvM View Post
    You didn't show what you have tried. As said, the posted code, using an input value as initializer doesn't work.

    Reading an input during reset and initializing a counter respectively should work. I have coded similar hardware more than once.
    You are right, but the thing is to make the input being read only once. Please take a look at this MWE:

    Code:
    --! Debounce hysteresis mechanism implementation
    architecture arch_debounce of entity_debounce is
    	
    begin
    	
    	process_debounce : process(clk)
    		
    		variable test : bolean := false;
    		
    		begin
    		
    		if (test = false)
    			test = true; -- this code is never run
    		end if;
    			
    	end process;
    The problem lies in the test variable. The if statement was designed to run some portion of code only once per whole device reset. Why doesnt it work?



    •   AltAdvertisment

        
       

  6. #6
    Super Moderator
    Points: 249,046, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,337
    Helped
    13177 / 13177
    Points
    249,046
    Level
    100

    Re: Initial value depending on the input

    Yes the code synthesis to nothing for two reasons:
    - nothing depends on the test signal
    - it's rewritten in combinational code

    Need to synthesize a register, in other words assign the new value on clock event.



  7. #7
    Member level 3
    Points: 1,349, Level: 8
    bremenpl's Avatar
    Join Date
    Jan 2013
    Posts
    61
    Helped
    0 / 0
    Points
    1,349
    Level
    8

    Re: Initial value depending on the input

    This is just an example. In the if statement part I had another statement that sets the counter variable, depending on the input signal. That did not work as well. How else can I create a 1 time execution situation?



  8. #8
    Super Moderator
    Points: 249,046, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,337
    Helped
    13177 / 13177
    Points
    249,046
    Level
    100

    Re: Initial value depending on the input

    Basically something like below. A reset synchronizer may be required to assure consistent action of the first clock edge.
    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    process (reset, clk)
    begin
      if reset = '1' then
        init_done <= '0';
      elsif rising_edge(clk) then
        if init_done = '0' then
          init_done <= '1';
          init_reg <= init_inp;
        end if;
      end if;
    end process;



    •   AltAdvertisment

        
       

  9. #9
    Member level 3
    Points: 1,349, Level: 8
    bremenpl's Avatar
    Join Date
    Jan 2013
    Posts
    61
    Helped
    0 / 0
    Points
    1,349
    Level
    8

    Re: Initial value depending on the input

    I see... But the problem here is that the mentioned reset signal is probably a signal entering the component. This design would require a physical reset to be performed a startup, this is not automatic, do I understand correctly?



  10. #10
    Super Moderator
    Points: 66,847, Level: 63
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    13,644
    Helped
    3122 / 3122
    Points
    66,847
    Level
    63

    Re: Initial value depending on the input

    Hi,

    I'm not sure wheter I understand the problem correctly.

    I assume you have one input and one output...and at powerup you want the output to have the same logic state as the input, but as soon as possible.
    The dilemma is, that the usual timing is:
    * Power up (FPGA signals are not initiated yet, thus high impedance)
    * time to load the FPGA configuration (FPGA signals are not initiated yet, thus high impedance)
    * FPGA is initiated and thus the output only can be configured as fix HIGH, LOW or Z (but you don't want fix H or L here)
    * FPGA is operating and now can react an output a signal depending on an input (but now it's too late for your idea)

    If my assumptions above are correct, then the only solution I see is to use an external resistor between input and output.
    This makes the "output" to get the same state as the "input" as long as the "output" is in Z state.
    As soon as you switch the "output" to H or L the FPGA controls the state (overriding the resistor)

    Klaus
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  11. #11
    Super Moderator
    Points: 249,046, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,337
    Helped
    13177 / 13177
    Points
    249,046
    Level
    100

    Re: Initial value depending on the input

    External hardware reset is the preferred method and should be always provided in a good design. Problems arise particularly, if the input clock is already present when the internal power on reset is released.

    It's nevertheless possible to generate an internal reset, although it can't be guaranteed to be completely free of metastable events.

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    SIGNAL reset_int           : STD_LOGIC := '1';
       SIGNAL reset_cnt           : INTEGER RANGE 0 TO 7 := 0;
       PROCESS (clk)
       BEGIN
          IF rising_edge(clk) THEN
             IF reset_cnt = 7 THEN
                reset_int <= '0';
             ELSE
                reset_cnt <= reset_cnt + 1;
             END IF;
          END IF;
       END PROCESS;

    - - - Updated - - -

    I'm not sure whether I understand the problem correctly.
    I understand that he wants to perform a specific action (set a register according to input signal) once after the POR has been released.

    Obviously, the FPGA IOs are already configured at this time.



--[[ ]]--