Monday, September 14, 2009

HDL Statemachines

Often times in HDL programming we need to describe what is know as a statemachine. For those unfamiliar with what statemachines are please refer to:

State machines require the use of both combinational logic and registers. The registers are used to hold the state variable information that is required to make the decision in the "next" clock cycle. The combinatorial logic is used to set the criteria for transitioning from one state to the next.

In this article I will show an example of how you might choose to implement a statemachine. This is not necessarily the best or most efficient way to implement one, but it is the way that I found easiest to understand.

If you have been following my HDL articles up to this point you probably noticed that I have only shown an architecture containing a single process. In the case of a statemachine, you must have at least 2 processes defined.
  • One process controls the updating of the state variables
  • One process handles the logic and navigation to the "next" state
Suppose we have a system that requires the use of a statemachine that contains two states, 0 and 1, which are mapped to a signal called "state". Also, suppose a logic variable that is used to navigate from one state to the next is define as "input" which can also take on the value of 0 or 1. Finally, lets suppose the logic that this statemachine follows is:

If state=0
If input=0
stay in state 0
go to state 1
End if;
If input=1
state in state 1
go to state 0
End if;
End if;

To create this system using a statemachine is quite simple. First lets create the state update process:

update_states: process (clk)
if(clk'EVENT and clk='1') then
current_state<=next_state; end if; end process;

The process above uses 3 signals.
  1. clk = This is the clk to the system, and in this case we are operating on the positive edge of the clock; however, you can make it operate on whatever part of the clock signal you wish.
  2. current_state = This is the current state we are in. This is to be used in the combinational logic.
  3. next_state = This is the next state that we will transition to in our statemachine.
You might be wondering, why do we have two state variables when you clearly defined having just one?

First, think of a REAL system that operates on clock edges; lets just say we have 2 casscaded positive edge triggered D-Flip Flops. What happens when you try to grab a value at the output of the first flip flop (which is the input to the second flip flop) and simultaneously try to write a new value at the input to 2nd flip flop?

The problem is, trying to simulateously read and write on a signal (or line) is undeterministic. We must remember that HDL uses concurrency, so we don't know whether the read or the write operation occurred first. Because of this, we must define two signals, one which is used to indicate the current state, that we can use to "read" from, and we define another signal that indicates the next state, that we can "write" to.

Now that we have our update_states process defined we can now work on the logic. In this example our logic is VERY simple.

    state_machine: process (clk)
    if(clk'EVENT and clk='1') then
    if (current_state='0') then
    if (input='0')
    next_state<=next_state; else next_state<='1'; end if; else if (input='1') next_state<=next_state; else next_state<='0'; end if; end if; end if; end process;

    And there you have it...your two processes that make the simple statemachine we defined. Of course, for this to work in an actual design, you will need to define the clk, current_state, next_state, and input signals. Which I am sure you can do if you read my previous tutorials.

    No comments:

    Post a Comment