# Initial value depending on the input

Status
Not open for further replies.

#### bremenpl

##### Member level 3
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).

I would appreciate all help.

Last edited:

#### FvM

##### Super Moderator
Staff member
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.

#### bremenpl

##### Member level 3

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...

#### FvM

##### Super Moderator
Staff member
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.

#### bremenpl

##### Member level 3
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?

#### FvM

##### Super Moderator
Staff member
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.

#### bremenpl

##### Member level 3
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?

#### FvM

##### Super Moderator
Staff member
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;

#### bremenpl

##### Member level 3
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?

#### KlausST

##### Super Moderator
Staff member
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

#### FvM

##### Super Moderator
Staff member
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.

Status
Not open for further replies.