Module 14

From Hamsterworks Wiki!

Jump to: navigation, search

Please make sure that you have completed the earlier modules of FPGA course.

Having problems with your code? Do I need to change something? Want a reference solution to the project? Email me at "nospam-hamster@snap.net.nz", after removing the "nospam-" bit. I'll try to get back to you in a day or so.

Contents

Aims of module

  • Look what a finite state machine is
  • Build a finite machine
  • Use VHDL constants
  • A bit of problem solving

Introduction to the project

For the project we are going to build a combination lock, which works as follows: - All switches must be turned off. - then switch 7 must be turned on - Then switch 6 must be turned on - then Switch 5 must be turned on - then Switch 4 must be turned on

If this sequence is followed, all the LEDs will turn on and stay on until all switches are moved back to off.

In software this would be quite easy - using the console for user input something like this would be quite close :

 while(1)
 {
  if(getchar() = '7' && getchar() = '6' && getchar() = '5' && getchar() = '4')
  {
    LEDs = 0xFF;
    getchar();
  } 
 }

To get the same result, we need to use a finite state machine (FSM).

These are very useful for a lot of different cases, from implementing user interfaces, interfacing with other systems or building memory controllers. There is a formalised way to document FSMs, but here's my somewhat less formal approach which works well when sketching designs on paper.

M14s1.png

At any point in time you are in the state indicated by a circle. On the next clock tick you must follow an arrow. All options must be mutually exclusive. I've added bold arrows to indicate the "no other arrow applies" option.

So when the system is in the "START" state the options are either: - If switches are set to "0000000" we go to the "START" state. - If switches are set to "1000000" we go to the "ONE RIGHT" state. - Otherwise we go to the "ERROR" state.

Likewise, in the "ERROR" state the options are - If switches are set to "0000000" we go to the "START" state. - Otherwise we go to the "ERROR" state.

If I have designed it correctly the only way to get to the "OPEN" state is to move the switches through "00000000", "10000000", "11000000", "11100000", then finally to "11110000"

Implementing in VHDL

Implementation is relatively easy.

You can either use enumerated types, but it is usually better to use constants.

  ...
  constant state_error     : STD_LOGIC_VECTOR(3 downto 0) := "0000";
  constant state_start     : STD_LOGIC_VECTOR(3 downto 0) := "0001";
  constant state_one_right : STD_LOGIC_VECTOR(3 downto 0) := "0010";
  ...
  signal state : STD_LOGIC_VECTOR(3 downto 0) := (others => '0'); 

If you use constants, then you can encode output signals within the states, ensuring that you get glitch-less signals. If you like, you could include this in your project to help with debugging:

  leds(3 downto 0) <= state;

In your project's process it is usually easiest to code it using a CASE statement like this:

  if rising_edge(clk) then
     case state is 
        when state_error =>
           case switches is 
           when "00000000" => state <= state_start;
           when others     => state <= state_error;
           end case;
        when state_start =>
           case switches is 
           when "00000000" => state <= state_start;
           when "10000000" => state <= state_one_right;
           when others     => state <= state_error;
           end case;
        when state_one_right =>
           case switches is 
           when "10000000" => state <= state_one_right;
           when "11000000" => state <= state_two_right;
           when others     => state <= state_error;
           end case;
        ....
        when others =>
           state <= state_error;           
     end case;
  end if;

Project 14.1 - Combination lock 1

  • Code the above FSM to implement the combination lock. To give some feedback on success set LEDs to "11111111", and
  • Test it in the simulator, using this in the test bench stimulus process
 switches <= "00000000";
 wait for 200 ns;
 switches <= "10000000";
 wait for 200 ns;
 switches <= "11000000";
 wait for 200 ns;
 switches <= "11100000";
 wait for 200 ns;
 switches <= "11110000";
 wait for 1000 ns;
 switches <= "00000000";
  • Try running it in hardware - it most probably won't work reliably - 50:50 if you are lucky.

The problem with switch bounce

This design will work perfectly well - as long as the switch contacts don't bounce. If they bounce the FSM will view that as an "otherwise" case and go to the error state.

Solutions are:

  • Debounce the switches in hardware
  • Debounce the switch signals using logic within the FPGA
  • Sample the switches at intervals that should mask any bounce (e.g. 1/10th of a second)
  • Update the FSM to allow for switch bounces.

The "debounce" solutions are all relatively hard, while updating the FSM will only need a few lines of code.

Project 14.2 - Combination lock 2

  • Trace through the FSM diagram to work out why a bounce causes it to fail
  • Update the FSM to ignore switch bounces
  • If you wish, test it in the simulator - here is stimulus that looks like four bouncing switches:
switches <= "00000000";
wait for 200 ns;

switches <= "10000000";
wait for 50 ns;
switches <= "00000000"; -- bounce
wait for 50 ns;
switches <= "10000000";
wait for 300 ns;

switches <= "11000000";
wait for 50 ns;
switches <= "10000000"; -- bounce
wait for 50 ns;
switches <= "11000000";
wait for 300 ns;

switches <= "11100000";
wait for 50 ns;
switches <= "11000000"; -- bounce
wait for 50 ns;
switches <= "11100000";
wait for 300 ns;

switches <= "11110000";
wait for 50 ns;
switches <= "11100000"; -- bounce
wait for 50 ns;
switches <= "11110000";
wait for 1000 ns;

switches <= "00000000";
  • Test it in hardware

Challenges

  • Can you make the LEDs flash off and on for a few seconds when an error occurs?
  • Can you make the board flash the LEDs in a pattern stored in BRAM when it reaches the "OPEN" state?

Ready to carry on?

Click here to carry on to the next module.

Personal tools