Tutorial Contents

Introduction
Comparison of State Machine Description Methods
The Purpose of This Tutorial
Creating a State Diagram
Implementation
Creating BLACKJACK Design
Using New Source File Wizard
Adding Ports
Adding Extra Ports
Defining Additional Variables
Adding a Reset State
Adding Initialization Actions
Adding a State to Request a Card
HDL Code Generation
Receiving and Handling of the New Card
Analyzing the Total Score
Testing the Final Score
Assigning Condition Priorities
Selecting State Encoding
Compiling the Design
Locating and Correcting Errors
Simulation
Conclusion

 

 

Introduction

State machine editors allow simple and easy graphical design entry. Since the state designs can be easily retargeted to any devices, the state editors are becoming very popular with designers who value technological independence. This tutorial is for Active-VHDL users who want to learn how to design with the state machine editor, which is used for graphical entry of VHDL designs.

 

Comparison of State Machine Description Methods

Lets consider a very simple state machine that is used for controlling traffic lights. Since the best way to start any state machine design is with verbal description, lets describe the operation of a traffic lights controller as follows:

The controller is based on a timer that switches all traffic lights in a predetermined sequence.
When the red light is on and the timer signals that the green light should be lit (GO_GREEN signal goes to High state), turn on the GREEN signal and turn off other signals. When the green light is on and the timer signals that the yellow light should be lit (GO_YELLOW signal goes to High state), turn on the YELLOW signal and turn off other signals. When the yellow light is on and the timer signals that the red light should be lit (GO_RED signal goes to High state), turn on the RED signal and turn off other signals.

State diagram is a graphical method of a state machine description. As an example, a state diagram for traffic lights controller is shown below:

 

State machines can be converted into HDL code, which can then be converted into a physical implementation (netlist) by logic synthesis software.

A VHDL description of a traffic lights controller is shown below:

entity lights is
port (CLK: in STD_LOGIC;
GO_GREEN: in STD_LOGIC;
GO_RED: in STD_LOGIC;
GO_YELLOW: in STD_LOGIC;
LIGHT_GREEN: out STD_LOGIC;
LIGHT_RED: out STD_LOGIC;
LIGHT_YELLOW: out STD_LOGIC);
end;

architecture lights_arch of lights is

type LIGHTS_type is (GREEN, RED, YELLOW);
signal LIGHTS: LIGHTS_type;

begin
process (CLK)

begin
if CLK'event and CLK = '1' then
case LIGHTS is
when GREEN =>
if GO_YELLOW='1' then
LIGHTS <= YELLOW;
end if;
when RED =>
if GO_GREEN='1' then
LIGHTS <= GREEN;
end if;
when YELLOW =>
if GO_RED='1' then
LIGHTS <= RED;
end if;
when others =>
null;
end case;
end if;
end process;

LIGHT_GREEN <= '1' when (LIGHTS = GREEN) else
'0' when (LIGHTS = RED) else
'0' when (LIGHTS = YELLOW) else
'0';

LIGHT_YELLOW <= '0' when (LIGHTS = GREEN) else
'0' when (LIGHTS = RED) else
'1' when (LIGHTS = YELLOW) else
'1';

LIGHT_RED <= '0' when (LIGHTS = GREEN) else
'1' when (LIGHTS = RED) else
'0' when (LIGHTS = YELLOW) else
'0';

end lights_arch;

The main advantages and disadvantages of state machine designs are listed in the table below.

Verbal Description State Diagram HDL Description

compact very compact lengthy
easy to read by humans very easy to read by humans hard to read by humans
difficult to implement easy to implement easy to implement
  self-documenting requires documentation

 

The Purpose of This Tutorial

This tutorial will teach you how to use Finite State Machine Editor for entering state machine diagrams and logic synthesis of the designs. We assume that you are familiar with the Active-VHDL application.

 

Creating a State Diagram

The sample design created in this tutorial is a state machine which plays the Blackjack game.

The purpose of the game is to select a number of cards which sum will be as close to 21 as possible. Each card has a decimal value between 2 and 11, where 11 is called ACE and can be counted as 1 if desired. The player with the highest number but lower than 21 will be the winner.

A request for an additional card is indicated by the SAY_CARD output (this signal is High or logical 1 when active), which is generated each time when the total sum of all cards is less then 17. However, it can never be generated if the total sum of cards exceeds 21.

The arrival of a new card is flagged by the NEW_CARD signal changing from 0 to 1.

The machine should output the SAY_BUST signal when the sum of cards exceeds 21. In case the total score is between 17 and 21, the machine should output the SAY_HOLD signal.

The total score should be shown on the TOTAL output. After reaching the SAY_HOLD or SAY_BUST condition, the machine should stay in the last state until the NEW_GAME (reset) signal is flagged on the input.

The NEW_GAME signal resets the state machine.

 

Implementation

The machine will be implemented by drawing a state diagram. The diagram will be automatically converted into the corresponding VHDL code. Then, you can verify the functionality of the machine by simulating the code in the VHDL simulator.

 

Creating BLACKJACK Design

  1. Start Active-VHDL. The Getting started window will appear.

 

  1. Select the Create new design option and click OK. This will open a series of successive wizard windows.
  2. Enter BLACKJACK as the design name.

 

  1. In the next wizard window, select Create an empty design.

 

  1. Move to the last wizard window by clicking the Next button and then click Finish to complete the new design setup.

 

 

Using New Source File Wizard

To open a new State Editor window, select State Diagram from New in the File menu.
Using a series of the successively appearing wizard windows, you can create a new design.

To create a state diagram pattern:

  1. Click Next in the New Source File Wizard window.

 

  1. In the New Source File Wizard - Name window, type in BLACKJACK as the file name and click the Next button.

 

  1. The Design Wizard - Ports window for entering I/ O signals (ports) will appear.

 

Note: The default file extension of state diagrams is *.ASF and the new file will be called BLACKJACK.ASF.

 

Adding Ports

To add a new port in the Design Wizard - Ports window, perform the following operations:

  1. Click the New button.
  2. Enter the port name in the Name box.
  3. Choose the port direction (in, out, inout, buffer) by selecting one of the options in the Port Direction field.

All assigned port names are displayed in the box above the New button and in the symbol preview area, which is located to the left of the port name listing.
Using the procedure described above, enter the following ports:

To enter the bus range [3;0] for the CARD signal, click the Port button to open the Port Type dialog. Then select the STD_LOGIC_VECTOR port type and enter the bus range using the arrays in the Range field.
You can also enter the bus range using the Array Indexes field in the Design Wizard - Ports dialog box.

 

 

Note that all the assigned I/O ports appear within the outline of the symbol, which is displayed on the left-hand side of the above window.

NOTE: State Editor supports only synchronous state machines, which means that all transitions from one state to another are performed only at the clock transitions and a design cannot operate without a clock signal.

  1. Click the Finish button after you have completed the I/ O ports setup. When the wizard prompts you for adding a clock port, click Yes.

 

The new state diagram created by Design Wizard is shown below:

NOTE: If you select multiple machines, they will be converted into separate and concurrent processes in VHDL.

 

 

Adding Extra Ports

Additional I/O ports can be added at any time to the state diagram by clicking the Output/ Input Port buttons, located at the bottom of the vertical toolbar. Since we need an output port showing the total score of the Blackjack game, lets add it now.

  1. Click the (Output Port) button and then click above the SAY_BUST port symbol. A new output port named Port1 will be placed above the SAY_BUST port.
  2. Click the port symbol you have just placed on the diagram with the right mouse button and select Properties from the shortcut menu. The Port Properties window will appear.
  3. Enter TOTAL in the Name box and select 4:0 in the Range box. Also, select the Output and Registered options.
  4. Click OK to complete the operation.

 

The Port Properties window allows you to define the selected input signal as a clock, and the output ports as either combinatorial or registered. The Registered ports hold the set value in an additional register. The combinatorial outputs change any time the input conditions change.

NOTE: Since the total value of all cards can be as high as 26 (the highest total at which a new card is drawn is 16 and the highest value of the new card can be 10), the TOTAL port has to have a binary range from 0 to 31 which requires 5 bits of data [4:0].

New output ports listed in the upper right-hand corner of the State Editor main screen should look as shown below:

 

 

Defining Additional Variables

The state machine needs to know if any of the cards is an ACE, because when the score exceeds 21 (with ACE counted as 11), the ACE can be counted as 1 to lower the total value below 21.
The following procedure describes how to define a new variable called Ace:

  1. Click the Signal button on the left tool-bar .
  2. Place the cursor below the Sreg0 text.

 

  1. Click the Signal 1 icon with the right mouse button and choose Properties from the shortcut menu. The Signal Properties window will appear.

 

  1. Type Ace in the Name field.
  2. Select the Boolean type.
  3. Click OK to complete the operation.

 

Adding a Reset State

Each state machine needs to be initialized. In case of the Blackjack game the initialization takes place when a new game is started. Lets add such initialization of all output ports to the state diagram right now.

  1. Click the State button located at the top of the vertical toolbar.
  2. Place the state symbol in the middle of the sheet, as shown below (use the left mouse button to place a new state and the right mouse button to cancel the state placement mode).The new state will automatically be called S1.

 

  1. To edit the state name, double click S1. An editing box will open.

 

  1. Replace S1 with Start by entering it in the editing box. To exit editing, click outside the edit box. The state bubble with the new name is shown below:

 

  1. Click within the blank area with the right mouse button and select Properties from the shortcut menu. The Machine Properties dialog box will open. This window is used to define global settings of the selected state machine. Some of the global settings such as Sreg0 are named automatically.

 

  1. Replace Sreg0 listed in the Name box with Action. This sets the name of the state machine signal used to store the current state in VHDL

 

The Machine Properties window has several tabs for grouping different options within the window. Click the Reset tab and select the following:

This will assure that the NEW_GAME signal will be used as machine reset and when it is activated, the machine will automatically enter the Start state.

 

  1. Click the OK button in the Machine Properties window. The state diagram should now look as shown below:

 

NOTE: The triangular reset symbol is not a state; it indicates that the associated transition will be executed any time this condition is met and will be carried out regardless of the current state of the machine. The reset transition is shown for documentation purpose only.

 

Adding Initialization Actions

Once the reset condition is met, the machine will enter the Start state. To define actions that follow the reset, we will need to create an entry action. The entry action is automatically attached to the top of the state symbol and indicates that the specified code is executed only once, when the machine enters this state.

  1. Click the Entry Action button .
  2. Position dot end of the mouse pointer over the Start state and click the left mouse button.
  3. In the edit box type in as follows:

Ace := false;
TOTAL <= "00000";
SAY_CARD <= '0';
SAY_HOLD <= '0';
SAY_BUST <= '0';

  1. Click the left mouse button outside the editing box.

Note that you have to use the VHDL syntax:

The above listed entry actions are shown below:

 

NOTE: Combinatorial output port assignments in the reset state are also used as default values in other states. This means that the output will be set to the default value in all states, even where the value was not explicitly indicated. In this example, SAY_BUST will be 0 in all states unless you add the SAY_BUST <= 1 action.

 

Adding a State to Request a Card

Once a reset has been performed, the state machine should start by requesting a card. This will be accomplished by adding the Hit_me state.

  1. Add the Hit_me state below the Start state (use the procedure described above for entering the Start state).
  2. To draw a transition between the Start and Hit_me, click the Transition button .
  3. Next, click anywhere within the Start and then Hit_me states. A line will be drawn between these states.
  4. To exit the editing mode, click the left mouse button outside the state bubbles.

NOTE: The transition from the Start state to the Hit_me state is unconditional and it will be automatically executed in the next clock cycle, after entering the Start state (it means that the Reset state will last for one clock cycle).

To flag the request for a new card, the SAY_CARD should be set to 1. Since this signal should remain active all the time in this state, we have to use the state action and not the entry action.

NOTE: State actions are executed on each clock cycle as long as the machine remains in the given state. Entry Action is performed only while entering the selected state. The Exit Action is performed upon leaving the previously active state.

  1. Click the State Action button .
  2. Position the dangling dot end of the mouse pointer over the Hit_me state and click the left mouse button.
  3. Type SAY_CARD <= '1' in the edit box.
  4. Click the left mouse button outside the editing box. After this operation the state diagram will look as shown below:

 

 

HDL Code Generation

At this point, a section of the state machine has been created. Before the design gets bigger, we will inspect the code being generated to show how diagram elements correspond to the generated code.

NOTE: The HDL code generation process checks for some diagram problems but does not check your VHDL statements. A full syntax check will be performed later on when the design is synthesized.

  1. Using the File tab of the Design Browser, click the Blkjack.asf file with the right mouse button.
  2. Choose the Generate VHDL option from the shortcut menu to view the generated code.

NOTE: It is essential that you learn to relate the code that is being generated to the elements on the drawing. State editor uses standard templates to create the VHDL design. Understanding VHDL constructs is very helpful while debugging a design with a VHDL simulator.

The VHDL code generated by State Editor can be divided into several sections.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

library METAMOR;
use METAMOR.ATTRIBUTES.all;

entity blackjack is
port (CARD: in STD_LOGIC_VECTOR (3 downto 0);
CLK: in STD_LOGIC;
NEW_CARD: in STD_LOGIC;
NEW_GAME: in STD_LOGIC;
SAY_BUST: out STD_LOGIC;
SAY_CARD: out STD_LOGIC;
SAY_HOLD: out STD_LOGIC;
TOTAL: out STD_LOGIC_VECTOR (4 downto 0));
end;

architecture blkjack_arch of blackjack is

-- SYMBOLIC ENCODED state machine: Action
type Action_type is (HIT_ME, Start);
signal Action: Action_type;

begin

--concurrent signal assignments
--diagram ACTIONS;

Action_machine: process (CLK)
--machine variables declarations
variable Ace: BOOLEAN;

begin

if CLK'event and CLK = '1' then
if NEW_GAME='1' then
Action <= Start;
Ace :=false;
TOTAL <="00000";

else
case Action is
when HIT_ME =>
when Start =>
Action <= HIT_ME;
when others =>
null;
end case;
end if;
end if;
end process;

-- signal assignment statements for combinatorial outputs
SAY_CARD_assignment:
SAY_CARD <= '1' when (Action = HIT_ME) else
'0';

SAY_HOLD_assignment:
SAY_HOLD <= '0';

SAY_BUST_assignment:
SAY_BUST <= '0';

end blackjack_arch;

 

Receiving and Handling of the New Card

Once a new card has been requested, the machine should wait until it is received. The arrival of the new card will be marked by the NEW_CARD signal. The following will add a design section that handles the NEW_CARD signal:

  1. Add a new state below the Hit_me state
  2. Rename the new state Got_it, using the same procedure that was used for changing S1 to Start.
  3. Click the right mouse button inside the state bubble, but outside the state name.
  4. Select Properties from the shortcut menu.
  5. Ensure that the Got_it name is in the Name field. Click OK.

 

  1. Add a transition from the Hit_me to Got_it state.
  2. Click the Condition button to add a condition to the newly drawn transition.
  3. Click the transition line.
  4. Type NEW_CARD='1' in the edit box.
  5. Click the mouse button outside the edit box.

NOTES:

Since these actions need to be executed only once while entering the state, the entry action will be used.
To assign entry actions to the state, use the Actions card in the State Properties window:

  1. Click the right mouse button inside the state bubble
  2. Select Properties in the shortcut menu
  3. Click the Actions tab.
  4. Type in the Entry box:
    TOTAL<=TOTAL+CARD;
    Ace:=(CARD=11) or Ace;
  5. Click the OK button to complete the operation.

 

NOTE: The above described actions must be defined as entry actions. Otherwise, the total will be incremented on each active clock edge as long as the machine remains in the Got_it state.

The state diagram should now look as shown below:

 

 

Analyzing the Total Score

Once the new card has been received, the total card score should be updated and tested. If it is less then 17, the state machine should request a new card and go back to the Hit_me state.

Adding a new card:

  1. Add the Test16 state below the Got_it state.
  2. Add transition from the Got_it state to the Test16 state.
  3. Add the NEW_CARD=0 condition to the above defined transition.

NOTE: Adding the NEW_CARD=0" condition prevents the state machine from using the same card more than once.

After completing this step the state diagram will look as shown below:

 

Detecting Hold/Bust conditions:

  1. Add the Test21 state below the Test16 state.
  2. Add a transition from the Test16 state to the Test21 state; assign to it the TOTAL > 16 condition.
  3. Add a transition from the Test16 state to the Hit_me state; assign to it the @ELSE condition.

NOTE: The @ELSE transition is executed when no other conditions are met in this state. This transition will be executed if the TOTAL value is 16 or less and will cause the machine to request a new card in the Hit_me state.

The state diagram with the 5 states should look the following:

 

 

Testing the Final Score

Once the machine gets to the Test 21 state, the total score is 17 or more. Now the state machine has to test if it has not exceeded 21. If not, it will flag the SAY_HOLD signal. If the score is over 21, the SAY_BUST signal should be activated, indicating that the machine has lost the game. Before flagging the SAY_BUST signal, the machine should check if any of the previously drawn cards was ACE. If there was Ace, it may decrement the total value by 10 to recover from the "bust" situation.

  1. Add two more states: Bust and Hold.

 

  1. Add a transition from the Test21 state to the Bust state and from the Test21 state to the Hold state.
  2. Add TOTAL < 22 condition to the Test21 Þ Hold transition.
  3. Add the SAY_HOLD <=1 state action to the Hold state.
  4. Add a transition from the Test21 state to the Test16 state with the ACE condition.

NOTE: Since ACE is a Boolean variable, no relational operators are required in the condition text.

  1. Click the Transition Action button , then click the transition line and type in the action text: TOTAL <= TOTAL-10. In this way you have added the action to the last transition.

NOTE: Transition actions allow to avoid redundant states. If you did not assign this action to a transition, another state would have to be created to execute the TOTAL <= TOTAL-10 action.

  1. Add the @ELSE condition to the Test21 Þ Bust transition.
  2. Add the SAY_BUST <=1 state action to the Bust state.

The final state diagram with all the states, transitions, conditions, and actions should look as shown below:

 

 

Assigning Condition Priorities

Note that in the Test21 state, both the TOTAL < 22 and ACE conditions can be met at the same time. In such a case, behavior of the machine depends on condition evaluation sequence. To avoid confusion, you should assign different priorities to each transition. Because our machine should first check if TOTAL is less than 22, assign the priority 1 to the "Test21 Þ Hold" transition and the priority 2 to the "Test21 Þ Test16" transition.

To change the transition priority:

  1. Click the transition line.
  2. Click the right mouse button to display the shortcut menu.
  3. Select the required priority level using the shortcut Priority command.
  4. Click the mouse button to complete the operation.

 

NOTE: Transitions without assigned priority are executed last.

 

Selecting State Encoding

When state machines are compiled into logic, the current states are stored in a "state" register, being a group of flip-flops. Each state is assigned to a separate flip-flop. However, if there are some concurrent state transitions, they may create a glitch in the combinatorial logic and the state machine can enter a wrong state. The recommended encoding type for all FPGAs is One-Hot which assigns such values to each state so that only one bit of a register transitions at any given time. One -Hot encoding, however, consumes more flip-flops because each state requires a bit in a register. For that reason it is not recommended for CPLDs which lack flip flop resources. State Editor supports one-hot and binary encoding. Other types of encoding can be created by manual assigning codes to each state.

The binary encoding method will be used in this tutorial to simplify design analysis in the simulator.

  1. Invoke the Machine Properties window. (To do so, click the blank state diagram area with the right mouse button).
  2. Select the Binary Encoded option and click OK.

 

NOTE: The Symbolic encoding command allows the synthesis tool to automatically select the preferred state encoding method. Metamor XVHDL defaults to binary encoding if the codes are not assigned to any values.

 

Compiling the Design

To compile the design, choose Compile from the Design menu or click the button. AVHDL will automatically generate VHDL code corresponding to the state diagram.

 

Locating and Correcting Errors

The output ports cannot be used for reading by a state machine. If reading of a port is required, it should be defined as bi-directional. Note that the 'TOTAL' signal is not readable because it is in the OUT mode and an error will be reported every time TOTAL appears on the right-hand side of signal assignment.

To correct this error:

  1. Click the TOTAL port symbol with the right mouse button.
  2. Select Properties from the shortcut menu.
  3. Change the port type to Bi-directional.
  4. Recompile the design - this time it should compile without errors.

 

Simulation

  1. To initialize the VHDL simulation process, select Initialize from the Simulation menu.
  2. In the Design Settings dialog on the Top-level Selection tab, select the top-level entity and click OK.

  1. Use the New Waveform option from the File menu or click the to open a new waveform window.
  2. Active-VHDL will automatically switch to the Structure tab of the Design Browser.
  3. Click the Root to display the signals in the bottom part of the Design Browser window.
  4. Select Add Signals from the Waveform menu The Add Signals dialog box will appear. Pressing the Ctrl key, select the following signals: CARD, CLK, NEW_CARD, NEW_GAME, SAY_BUST, SAY_CARD, SAY_HOLD, TOTAL..

 

  1. Click Add to add the signals to the Waveform window for observation.

To assign stimulators to the signals:

Using the procedure described above, assign the following stimulators to the signals:

NEW_CARD 0 0, 1 80 -r 100
NEW_GAME 1 0, 0 20 -r 600
CARD 16#0 0, 16#A 100, 16#3 200, 16#8 300
CLK 0 0, 1 5 -r 10

The above formulas are based on a very simple syntax:
value [ time { , value time } [ -r period ] ]

where:

[ ] Square brackets indicate an optional item
{ } Braces indicate an optional item which can be repeated

 

The signal names in the Waveform window should look as below:

  1. Set the simulation step to 100ns in the Increase/ Decrease time spin box located in the main toolbar.
  2. Perform several simulation steps using the Run Until option from the Simulation menu.

You should get results similar to the shown below:

 

 

Conclusion

As shown above, the State Editor is a powerful tool for creating control logic designs in VHDL. The graphical diagrams provide excellent documentation of the design and allow you to generate efficient and reliable synthesis results.