- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, guys!
So, I'm new here. I'm a student whose lab professor gave him the following assignment. Translated from spanish to english, it reads like this:An electrical engine is controlled by a single button. When the button is pushed, the engine is turned on. When the button is pushed again, the engine returns to 'off' status. Syntethize the engine's control circuit in VHDL.
And then I have to program a FPGA with it, SignalTap it, and show the professor that it works as intended. The FPGA I'm using is a Cyclone III EP3C16F484C6. Since the pushable button I use continuously sends a '1' signal when it's not pushed, and a '0' signal while it's pushed, I wrote the following VHDL code for the assignment. ENTITY enginecontrol IS
PORT (clk,button: IN BIT; engine: OUT BIT);
END enginecontrol;
ARCHITECTURE behavior OF enginecontrol IS
TYPE statesec IS (A,B,C,D);
SIGNAL state: statesec:=A;
BEGIN
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk ='1') THEN
CASE state IS
WHEN A =>
IF button ='0' THEN
state<=B;
ELSE
state<=A;
END IF;
WHEN B =>
IF button ='1' THEN
state<=C;
ELSE
state<=B;
END IF;
WHEN C =>
IF button ='0' THEN
state<=D;
ELSE
state<=C;
END IF;
WHEN D =>
IF button='1' THEN
state<=A;
ELSE
state<=D;
END IF;
END CASE;
END IF;
END PROCESS;
engine<= '0' WHEN state=A ELSE
'1' WHEN state=B ELSE
'1' WHEN state=C ELSE
'0';
END behavior;
Here, remember, button pushed is 0 and button released is 1. Engine 'on' is 1 and engine 'off' is 0. This code, I believe, clearly describes a state machine with four possible states. It starts at state A, with the engine off. If the button is pushed, it goes to state B, and the engine turns on. It will remain on state B as long as the button is pushed, and when the button is released, it goes to state C, engine still on. Push the button again, and you get state D, engine off. Let it go and the cycle begins again, at state A. This is the desired behavior! Always the same, reliable... But the real behavior is... random! Around 70% of the time, when you release a button, it goes from state B to A, instead of C, or from state D to C, instead of A. This, of course, has undesired results on the output. Nowhere in the code I can see anything that could produce this behavior! And around 30% of the time, releasing a pushed button works as intended, and the machine goes to the correct next state. Since I won't be seeing my lab professor again until January 10th, can you guys tell me why this is happening? Many thanks for your time and help!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
According to your spec I don't need state machine just toggle a register upon push.
Regarding you state transitions, remeber push is momentary and may suffer bouncing. you can add debouncing logic.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I assume by bouncing you mean the fact that you can push the button just for a moment, but several '0' signals are sent, instead of just one. Yes, I knew and explained that... This is why if I only used a toggle, the circuit would never work as intended. The state machine I made is my way of filtering off that bouncing, it is my 'debouncing logic'. Why doesn't it work? Could you explain to me how would you do it instead?
Many thanks!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Or you mean that sometimes the button sends '0' signals even after being released already? Even after having sent some '1' -I'm released!- signals, a rogue '0' signal can come after that??
If that's the case... I have no idea how to overcome it.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are different ways to debounce keys.
In your case you want to detect push = '0' once only over some practical interval. For example I will run a counter for 20 msec. pseudocode, on the clock edge...
if push = '0' and count = max then -- first push detection
push_L <= '1';
end if;
if push = '0' and push_L = '0' then
count <= 0;
end if;
if count < max then
count <= count + 1;
else
push_L <= '0';
end if;
if push = '0' and push_L = '0' then
push_T <= not push_T; -- to your engine, hopefully without smoke
end if;
you will need to test this logic as I wrote it off head.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can also use your state machine for debouncing but add extra interval of time. This could be simpler to control:
s0: detect push = 0, decide toggle, move to s1 s1: stay for some time ignoring key, then move to s0- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The second solution you suggested was perfect. I added a counter to lock each state upon arrival for 100 mseconds, staying just there and ignoring all button input during this small lock interval. Now the machine works 100% as intended.
Thanks a lot for your help! You've made an student happy!
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page