85
ECSE 323: Digital System Design Payom Meshgin (260431193) Yi Qing Xiao (260429342) Group #27 4/16/2012 Laboratory 5: System Integration Prof. Katarzyna Radecka

ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

  • Upload
    piohm

  • View
    392

  • Download
    3

Embed Size (px)

DESCRIPTION

Property of Payom Meshgin;McGill University, Montreal, Quebec, Canada

Citation preview

Page 1: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

ECSE 323: Digital System

Design

Payom Meshgin (260431193)

Yi Qing Xiao (260429342)

Group #27

4/16/2012

Laboratory 5: System Integration

Prof. Katarzyna Radecka

Page 2: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

i Table of Contents

TABLE OF CONTENTS

Table of Contents ..................................................................................................................... i

Table of Figures ....................................................................................................................... v

Introduction ............................................................................................................................. 1

Lab 5: The Controller ai_control ............................................................................................... 3

Discussion of the design ....................................................................................................... 3

Description of the I/O pins .................................................................................................... 4

FSM schematics ................................................................................................................... 6

Pseudocode ........................................................................................................................ 11

Other figures ....................................................................................................................... 13

Reports ............................................................................................................................... 14

Controller implementation .................................................................................................. 14

Input pins: ....................................................................................................................... 14

Output pins: .................................................................................................................... 15

Simulation waveforms ........................................................................................................ 15

Discussion of Overall Design ................................................................................................... 18

custom_types: Custom Data Types .................................................................................... 19

ttt: Overall Design .............................................................................................................. 20

Description .................................................................................................................... 20

Description of the I/O pins .............................................................................................. 20

Pin Assignments ............................................................................................................ 22

Reports ........................................................................................................................... 23

Simulations and Waveforms ........................................................................................... 24

Page 3: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

ii Table of Contents

sys_led_state: LED Current State Display ............................................................................ 27

Description ..................................................................................................................... 27

Description of the I/O pins ............................................................................................... 27

Simulations and Waveforms ........................................................................................... 28

Pseudocode ................................................................................................................... 28

GM_LED: SEVEN SEGMENT LED DISPLAY ................................................................ 29

DESCRIPTION ................................................................................................................ 29

DESCRIPTION OF THE I/O PINS ...................................................................................... 30

SIMULATIONS AND WAVEFORMS ................................................................................. 31

Pseudocode ....................................................................................................................34

ga_array: Game Table ........................................................................................................ 36

Description .................................................................................................................... 36

Description of the I/O pins ............................................................................................... 37

Simulations and Waveforms ............................................................................................38

Pseudocode ................................................................................................................... 39

ga_array_mux: Multiplexer for the Game Table .................................................................. 39

Description .................................................................................................................... 39

Description of the I/O pins .............................................................................................. 40

Simulations and Waveforms ........................................................................................... 42

Pseudocode ....................................................................................................................43

gm_status: Check Current Game Status ............................................................................. 44

Description .................................................................................................................... 44

Description of the I/O pins .............................................................................................. 45

Simulations and Waveforms ........................................................................................... 46

Page 4: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

iii Table of Contents

Pseudocode ................................................................................................................... 46

hp_wait: Wait for HP Move .................................................................................................. 47

Description .................................................................................................................... 48

Description of the I/O pins .............................................................................................. 48

Simulations and Waveforms ........................................................................................... 49

Pseudocode ................................................................................................................... 50

ai_find_win: Try to Win Or Block ......................................................................................... 51

Description ..................................................................................................................... 51

Description of the I/O pins .............................................................................................. 52

Simulations and Waveforms ............................................................................................ 53

Pseudocode ................................................................................................................... 54

ai_fork: Try to Make a Fork ................................................................................................. 56

Description .................................................................................................................... 56

Description of the I/O pins ............................................................................................... 57

Simulations and Waveforms ........................................................................................... 58

Pseudocode ................................................................................................................... 59

ai_block_fork: Try to Block a Fork ....................................................................................... 61

Description .................................................................................................................... 61

Description of the I/O pins .............................................................................................. 62

Simulations and Waveforms ........................................................................................... 63

Pseudocode ................................................................................................................... 64

ai_direct_write: Other Strategies ........................................................................................ 67

Description .................................................................................................................... 68

Description of the I/O pins .............................................................................................. 68

Page 5: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

iv Table of Contents

Simulations and Waveforms ........................................................................................... 69

Pseudocode .................................................................................................................... 70

ai_random: Very Dumb AI ................................................................................................... 71

Description ..................................................................................................................... 71

Description of the I/O pins ............................................................................................... 72

Simulations and Waveforms ............................................................................................ 73

Pseudocode .................................................................................................................... 73

Proposed modifications to Design .......................................................................................... 74

Problems encountered ........................................................................................................... 75

Conclusion .............................................................................................................................. 76

Appendix ................................................................................................................................ 77

Appendix I: Global Architecture of the Game (ttt.vhd) ......................................................... 77

Appendix II: Finite State Machine ........................................................................................ 78

Page 6: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

v Table of Figures

TABLE OF FIGURES

Figure 1: Block Diagram of the Ai_Control Component ............................................................ 6

Figure 2: FSM DIAGRAM, LEVEL = 1 ......................................................................................... 7

Figure 3: FSM DIAGRAM, LEVEL = 2 ........................................................................................ 8

Figure 4: FSM DIAGRAM, LEVEL = 3 ........................................................................................ 9

Figure 5: FSM DIAGRAM, LEVEL = 4 ....................................................................................... 10

Figure 6: RTL diagram of the Game Controller ........................................................................ 13

Figure 7: Compilation Report for g27_control.vhd ................................................................... 14

Figure 8: Timing Analysis Report for g27_control.vhd ............................................................. 14

Figure 9: Simulation of the controller ...................................................................................... 15

Figure 10: Simulation of the controller .................................................................................... 15

Figure 11: Simulation of the controller ................................................................................... 16

Figure 12: Simulation of the controller .................................................................................... 17

Figure 13: Simulation of the controller .................................................................................... 18

Figure 14: Convention Used for the std_table Type ................................................................ 19

Figure 15: Table of all State Names Defined by the Custom_Types Package .......................... 20

Figure 16: Block Diagram of the ttt Component ..................................................................... 22

Figure 17: Input Pin Assignments for g27_ttt.vhd ................................................................... 22

Figure 18: Input Pin Assignments for g27_ttt.vhd .................................................................... 23

Figure 19: Flow Summary for g27_ttt.vhd ............................................................................... 23

Figure 20: Resource Utilisation by Entity ................................................................................ 24

Figure 21: Timing Analysis Summary ..................................................................................... 24

Figure 22: Overall Simulation of the Game ............................................................................. 25

Figure 23: Exceptional Case Handling in the Game ................................................................. 26

Figure 24: Block Diagram of the sys_led_state component .................................................... 28

Figure 25: Block Diagram of the gm_led Component .............................................................. 31

Figure 26: Bit Assignment for the Seven-Segment Display ...................................................... 32

Figure 27: Initial Simulations of the gm_led Component ......................................................... 32

Figure 28: Simulation of the gm_led Component Through Multiple States.............................. 33

Page 7: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

vi Table of Figures

Figure 29: Final Simulation of the gm_led Component Testing the Dimming ..........................34

Figure 30: Block Diagram of the ga_array component .............................................................38

Figure 31: Simulation Waveform for the ga_array Component ............................................... 39

Figure 32: Block Diagram of the ga_array_mux component ................................................... 42

Figure 33: Simulation Waveform for the ga_array_mux Component .......................................43

Figure 34: Block Diagram of the gm_status Component ......................................................... 46

Figure 35: Simulation Waveform for the gm_status Component ............................................ 46

Figure 36: Block Diagram of the hp_wait Component ............................................................ 49

Figure 37: Simulation Waveform of the hp_wait component .................................................. 50

Figure 38: Block Diagram of the ai_find_win Component ........................................................ 53

Figure 39: Waveform of ai_find_win covering all possible winning rows .................................. 53

Figure 40: Waveform of ai_find_win covering all possible Losing rows ................................... 54

Figure 41: Waveform of ai_find_win covering Invalid Rows .................................................... 54

Figure 42: Block Diagram of the ai_fork Component .............................................................. 58

Figure 43: Waveform for ai_fork ............................................................................................. 58

Figure 44: Block Diagram of the ai_block_fork Component .................................................... 63

Figure 45: First Simulation Waveform for the ai_block_fork Component ................................ 63

Figure 46: Second Simulation Waveform for the ai_block_fork Component ........................... 64

Figure 47: Third Simulation Waveform for the ai_block_fork Component .............................. 64

Figure 48: Block Diagram of the ai_direct_write Component ................................................. 69

Figure 49: Waveform of AI_direct_write for the first two substrategies ................................... 70

Figure 50: Waveform of AI_direct_write for the Last two substrategies ................................... 70

Figure 51: Scanning order of the ai_random component ......................................................... 72

Figure 52: Block Diagram of the ai_random Component ......................................................... 73

Figure 53: Simulation Waveform for the ai_random component ............................................. 73

Figure 54: Block Diagram of the Game .................................................................................... 77

Figure 55: Finite State Machine diagram for the complete game ............................................. 78

Page 8: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

1 Discussion of the design

INTRODUCTION

For the purpose of the laboratory component of the Digital System Design course, our team

was tasked to develop a functioning Tic-Tac-Toe game implemented on the Altera Cyclone II

board using the Altera Quartus II software.

The 3x3 Tic-Tac-Toe table is stored in a 2-dimensional array holding 2-bit values. Instead of

using “X”s and “O”s as symbols, these symbols are given a numerical representation: an “X”

mark is denoted by a “01” value while an “O” mark is denoted by a “11” value. The human

player, or HP, always plays “X” marks, while the computer plays “O” marks only.

In the final part of the lab, we had to integrate the final design of the game on the board. In

order to achieve the complete functionality of the game, we have opted to construct the game

using an entirely original design as we envisioned a more robust design structure than was

recommended. This modular design helped not only debug the functions we wrote mush more

easily, but it also provided us with greater control over each part of the design.

We implemented the

Furthermore, our AI’s game playing strategy is very strong; much more so than in the

recommended design in the lab. Finally, the AI can decide to play offensively or defensively

depending on the situation, rather than make the decision based on user input. Hence, none of

the designs we had created in the previous parts of the lab have been retained in our final

design.

In our design, we have notably implemented the following extra features:

AI has multiple stages of difficulty ranging from “dumb” to exclusively offensive to

exclusively defensive to “expert”

A complete user interface utilizing the 4 seven-segment LED display, indicating the

current state of the game table and outputting messages to the user (more about this

later)

Player can specify whether the human player or the AI would start the game

Page 9: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

2 Discussion of the design

First, we will discuss the controller element at the heart of the design for the 5th lab. Then, we

will discuss the rest of the design, explaining what each component does each step of the way.

Page 10: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

3 Discussion of the design

LAB 5: THE CONTROLLER AI_CONTROL

DISCUSSION OF THE DESIGN

The controller functions as the state machine of the overall design. Based on the current state

of the state machine and the input control signals, the state machine reaches a new state. The

controller, at the rising edge of the clock, outputs the current state of the finite state machine

to all the components that only function based on the current state.

States described in the state machine:

sg: Start Game (Initialize all components of the game). Whenever the reset button is

pressed, this will become the new state.

hp_move: Human player’s move (remain in this state until the human player makes a

move, in which case the next state is the status state)

status: Check whether the game has ended, either as a tie (next state becomes “tie”), a

human player win (next state becomes “loss”). If the game is not over, change the state

to the appropriate game strategy state dictated by the current difficulty level.

States running the game strategy for the AI. If the computer makes a move, the next state

becomes “AI_Status”. If not, the next state will depend on the current difficulty level set by

the human player (more on this later).

o ai_try_win: If there exists a row containing 2 “O” marks and an empty space,

then AI places an “O” mark in the empty space to win the game.

o ai_try_block: If there exists a row containing 2 “X” marks and an empty space,

then AI places an “O” mark in the empty space to stop the HP from winning.

o ai_try_fork: If there exists a move that creates a fork (two rows each containing

a pair of “O” marks and a single empty space), then the AI will make that move.

o ai_try_blockfork: If the HP is on the verge of creating a fork, make a move to

block the creation of the fork.

o ai_try_direct: Small sub strategy:

If the centre cell of the game table is empty, the AI will play there

Page 11: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

4 Description of the I/O pins

If a corner cell is occupied by an “X” mark and if the opposite corner cell

is empty, the AI will place an “O” mark in that empty cell.

AI adds an “O” mark in the first free corner cell

AI adds an “O” mark in the first free side cell.

o ai_random: This state is the only reached when the difficulty level “user_levl” is

set to 0. AI scans through the table in order until an empty cell is detected. AI

places an “O” mark in that cell

ai_status: Similar to “status”, except that it checks whether the game has ended by a

win by the AI (next state = “Win”) or by a tie (next state = “Tie”). If the human player can

still play, the next state becomes “HP_move”.

Loss: End State of Game caused by the loss of the AI. Game starts again upon the value

of the Reset signal

Tie: End State of Game caused by a tie game (the table is completely filled with “O” and

“X” marks without either the HP or the AI winning). Game starts again upon the value of

the Reset signal

Win: End State of Game caused by the AI winning. Game starts again upon the value of

the Reset signal

DESCRIPTION OF THE I/O PINS

Input Pins:

reset: std_logic

o User input

o Indicates a request to reset the game

clock: std_logic

start: std_logic

o User input

o Required to start the actual game (i.e. allows the human player or the AI to

make a move)

hp_mm: std_logic

Page 12: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

5 Description of the I/O pins

o Outputted by the “hp_wait” component

o Indicates that the human player has made a move

ai_mm: std_logic

o Outputted by each component dealing with the strategy of the AI

o Indicates that the human player has made a move

ai_loss: std_logic

o Outputted by the “gm_status” component

o Indicates that the game has ended and that the AI has lost

ai_tie: std_logic

o Outputted by the “gm_status” component

o Indicates that the game has ended in a tie

ai_win: std_logic

o Outputted by the “gm_status” component

o Indicates that the game has ended and that the AI has won

level: std_logic_vector(1 downto 0)

o User Input

o Specifies the difficulty level of the AI

hp_start: std_logic

o User Input

o Specifies whether the human player (when set to ‘0’) or the AI (when set to ‘1’)

will start the game

Output Pins:

cur_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

Page 13: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

6 FSM schematics

FIGURE 1: BLOCK DIAGRAM OF THE AI_CONTROL COMPONENT

FSM SCHEMATICS

Unfortunately, due to the complex behaviour of our state machine, it is be preferable to

decompose the state machine based on the value of the difficulty level signal “level”, yielding

four different state machine diagrams. For the sake of completeness, a complete finite state

machine diagram generated by the Quartus II software is included in the appendix (see Figure

55: Finite State Machine diagram for the complete game for more details).

Please note that in all cases, the next state will remain the current state if the transition

conditions specified in the diagrams below are not met.

Page 14: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

7 FSM schematics

FIGURE 2: FSM DIAGRAM, LEVEL = 1

Page 15: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

8 FSM schematics

FIGURE 3: FSM DIAGRAM, LEVEL = 2

Page 16: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

9 FSM schematics

FIGURE 4: FSM DIAGRAM, LEVEL = 3

Page 17: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

10 FSM schematics

FIGURE 5: FSM DIAGRAM, LEVEL = 4

Page 18: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

11 Pseudocode

PSEUDOCODE

if (clock='1' and clock'event){ if (reset='0'){ fstate = sg; else fstate = reg_fstate; } } reg_cur_state = sg; cur_state = sg; switch(fstate){ case sg: if ((start == '0') and hp_start == '0'){ reg_fstate = hp_move; } else if ((start == '0') and hp_start == '1'){ reg_fstate = status; else reg_fstate = sg; } reg_cur_state = sg; case hp_move: if (hp_mm == '1'){ reg_fstate = status; else reg_fstate = hp_move; } reg_cur_state = hp_move; case status: if ai_loss == '1'{ reg_fstate = loss; } else if ai_tie == '1'{ reg_fstate = tie; } else if ai_win == '1'{ reg_fstate = win; } else if ((((not((level(1) == '1')) and not((level(0) == '1'))) and not((ai_tie == '1'))) and not((ai_loss == '1')))){ reg_fstate = ai_random; } else if (((((level(1) == '1') and not((level(0) == '1'))) and not((ai_tie == '1'))) and not((ai_loss == '1')))){ reg_fstate = ai_try_block; else reg_fstate = ai_try_win; } reg_cur_state = status; case ai_random: if (ai_mm == '1'){ reg_fstate = ai_status; else

Page 19: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

12 Pseudocode

reg_fstate = ai_random; } reg_cur_state = ai_random; case ai_try_win: if (ai_mm == '1'){ reg_fstate = ai_status; } else if (((not((level(1) == '1')) and (level(0) == '1')) and not((ai_win == '1')))){ reg_fstate = ai_try_fork; else reg_fstate = ai_try_block; } reg_cur_state = ai_try_win; case ai_try_fork: if ((ai_mm == '1')){ reg_fstate = ai_status; } else if (((not((level(1) == '1')) and (level(0) == '1')) and not((ai_mm == '1')))){ reg_fstate = ai_try_direct; else reg_fstate = ai_try_blockfork; } reg_cur_state = ai_try_fork; case ai_try_block: if ((ai_mm == '1')){ reg_fstate = ai_status; } else if ((((level(1) == '1') and not((level(0) == '1'))) and not((ai_mm == '1')))){ reg_fstate = ai_try_blockfork; else reg_fstate = ai_try_fork; } reg_cur_state = ai_try_block; case ai_try_blockfork: if ((ai_mm == '1')){ reg_fstate = ai_status; else reg_fstate = ai_try_direct; } reg_cur_state = ai_try_blockfork; case ai_try_direct: if ((ai_mm == '1')){ reg_fstate = ai_status; else reg_fstate = ai_try_direct; } reg_cur_state = ai_try_direct; case ai_status: if (ai_loss == '1'){

Page 20: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

13 Other figures

reg_fstate = loss; } else if (ai_tie == '1'){ reg_fstate = tie; } else if (ai_win == '1'){ reg_fstate = win; else reg_fstate = hp_move; } reg_cur_state = ai_status; case loss: reg_fstate = loss; reg_cur_state = loss; case tie: reg_fstate = tie; reg_cur_state = tie; case win: reg_fstate = win; reg_cur_state = win; case others: reg_cur_state = sg; } cur_state = reg_cur_state;

OTHER FIGURES

Here’s the RTL diagram of the controller. The yellow box represents the finite state machine.

As shown previously, the controller simply encapsulates the finite state machine.

FIGURE 6: RTL DIAGRAM OF THE GAME CONTROLLER

ai_loss

ai_mm

ai_tie

ai_win

clk

hp_mm

hp_start

reset

start

level[1..0]

sg

hp_move

status

ai_try_win

ai_try_block

ai_try_fork

ai_try_blockfork

ai_try_direct

ai_random

ai_status

loss

tie

win

reset

clock

start

hp_mm

ai_mm

ai_loss

ai_tie

ai_win

hp_start

cur_state.sg

cur_state.hp_move

cur_state.status

cur_state.ai_try_win

cur_state.ai_try_block

cur_state.ai_try_fork

cur_state.ai_try_blockfork

cur_state.ai_try_direct

cur_state.ai_random

cur_state.ai_status

cur_state.loss

cur_state.tie

cur_state.win

level[1..0]

fstate

Page 21: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

14 Reports

REPORTS

g27_control.vhd

Total logic elements 30 / 18,752 ( < 1 % )

Total combinational functions 30 / 18,752 ( < 1 % )

Dedicated logic registers 13 / 18,752 ( < 1 % )

Total registers 13

Total pins 24 / 315 ( 8 % ) FIGURE 7: COMPILATION REPORT FOR G27_CONTROL.VHD

Type Actual Time

From To

Worst-case tsu

5.648 ns reset fstate.ai_random

Worst-case tco

7.344 ns fstate.status cur_state.status

Worst-case th

0.085 ns level[0] fstate.ai_try_win

FIGURE 8: TIMING ANALYSIS REPORT FOR G27_CONTROL.VHD

CONTROLLER IMPLEMENTATION

To test the functionality of the controller on the Altera board, we made use of the red and

LEDs as outputs displaying the current state that the controller is in. We also used the toggle

switches as the input signals of the state machine. A push button was used as a manual clock

to allow for precise testing on the board. Described below are the pins we assigned during the

implementation of the “game controller”.

INPUT PINS:

Signal Name on

board Pin

Location

start SW8 PIN_M1

hp_start SW7 PIN_M2

hp_mm SW6 PIN_U11

ai_mm SW5 PIN_U12

ai_loss SW4 PIN_W12

ai_tie SW3 PIN_V12

ai_win SW2 PIN_M22

clock KEY0 PIN_R22

Page 22: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

15 Simulation waveforms

level[1] SW1 PIN_L21

level[0] SW0 PIN_L22 FIGURE 9: SIMULATION OF THE CONTROLLER

OUTPUT PINS:

Signal Name on

board Pin

Location

cur_state.sg LEDR9 PIN_R17

cur_state.hp_move LEDR8 PIN_R18

cur_state.status LEDR7 PIN_U18

cur_state.ai_try_win LEDR6 PIN_Y18

cur_state.ai_try_block LEDR5 PIN_V19

cur_state.ai_try_fork LEDR4 PIN_T18

cur_state.ai_try_blockfork LEDR3 PIN_Y19

cur_state.ai_try_direct LEDR2 PIN_U19

cur_state.ai_random LEDR1 PIN_R19

cur_state.ai_status LEDR0 PIN_R20

cur_state.loss LEDG7 PIN_Y21

cur_state.tie LEDG6 PIN_Y22

cur_state.win LEDG5 PIN_W21 FIGURE 10: SIMULATION OF THE CONTROLLER

SIMULATION WAVEFORMS

Before testing the design on the board, we simulated the behaviour of the finite state machine.

First, we tested the flow of the controller for each level of difficulty specified by the input signal

“level”, as well as the behaviour at the beginning of the game (when the “reset” and “start”

signals need to be set to ‘0’ before the human player can start playing). As long as “ai_mm” is

not set, the controller should go through all possible strategy states.

In the waveform below, we observe that indeed, the game does not start until the user presses

the start button (i.e. “start” = 0). Also, we see that the strategy states chosen by the controller

for each possible value of “level” follow exactly what the state diagrams indicated, that is, we

have the following state flows for

“level” = ‘0’: status => ai_random

Page 23: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

16 Simulation waveforms

“level” = ‘1’: status => ai_try_win => ai_try_fork => ai_try_direct => ai_random

“level” = ‘2’: status => ai_try_block => ai_try_block_fork => ai_try_direct

“level” = ‘3’: status => ai_try_win => ai_try_block => ai_try_fork => ai_try_block_fork

=> ai_try_direct

Furthermore, in this simulation, we also observe that the states “ai_try_direct” and “hp_move”

wait until input signals “hp_mm” or “ai_mm” are asserted.

FIGURE 11: SIMULATION OF THE CONTROLLER

Our next test for the controller checks if the controller can react to a move being made by a

strategy state (i.e. “ai_mm” = ‘1’). To perform this test, we modified the previous simulation by

specifying the difficulty “level” to ‘11’, enabling all the strategy states. Furthermore, we

conducted multiple tests where the “ai_mm” signal changes at a different time, making sure

that the next state following any move by the AI (“ai_mm” = ‘1’) is the “ai_status” state (the

state that check the current status of the game). The waveform below confirms that the

component behaves as expected.

Page 24: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

17 Simulation waveforms

FIGURE 12: SIMULATION OF THE CONTROLLER

Our last simulation tests all end game scenarios, as well as the functionality of the “hp_start”

input signal, which indicates whether or not the AI starts the game and is checked when the

“start” input signal is set to ‘0’. An end game scenario (either “AI win”, “HP win” or “tie”) is

outputted by the “gm_status” component, which is only active during the “status” (after the

human player made a move) and “ai_status” (after the AI made a move) states. We simulate

the six final outcomes where any of the three game termination input signals (caused by an AI

win, a HP win or a tie game) are asserted during either the “status” or “ai_status” states

The waveform below is the result of these tests. As we can see, the controller is not affected by

the game termination signal until the current state is one of the two listed above. In addition,

when one of the game termination input signals (“ai_loss”, “ai_tie” and “ai_win”) is set to ‘1’,

the appropriate next state (“loss”, “tie”, “win”) is reached.

Page 25: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

18 Simulation waveforms

FIGURE 13: SIMULATION OF THE CONTROLLER

Also, we verify the functionality of the “hp_start” input by asserting the signal in the last three

tests (in which we focus on the behaviour of the controller after the AI makes a move). As seen

below, the AI makes its move right after the game starts.

Even though not all possible inputs were simulated for this component, the VHDL code for the

controller is so repetitive (i.e. the code follows a very straight-forward structure) that we

expect the whole controller to function correctly after the simulations above.

Finally, while these simulations involve inputs that are active only during a clock cycle, testing

the controller on the board in real time showed that controller works even if an input is held

over multiple clock cycles. Therefore, we can confidently say that the controller works

completely as intended.

DISCUSSION OF OVERALL DESIGN

Page 26: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

19 custom_types: Custom Data Types

Our design of the Tic-Tac-Toe game is segmented into many simple components that are

mutually connected to one another. All components are synchronised by a common clock,

either directly (the clock is an input of the component) or indirectly (the clock changes the

value of the main input signal of the component.

Here is a list of all the components we used in our final design (ttt.vhd):

control – Game Controller

sys_led_state – LED Current State Display

gm_led – Seven segment LED Display

ga_array – Game Table

ga_array_mux – Multiplexer for the Game Table

gm_status – Game Status Check

hp_wait – Wait for HP move

ai_find_win – Try to Win

ai_fork – Try to Create a Fork

ai_block_fork – Try to Block a Fork

ai_direct_write – Other Strategies

ai_random – Very Dumb AI

CUSTOM_TYPES: CUSTOM DATA TYPES

Although not a component, the “custom_types.vhd” file contains a package that defines the

two custom data types used by all components in our global design. These are:

std_table: array (0 to 2, 0 to 2) of std_logic_vector(1 downto 0)

o 2-dimensional representation of the game table “ga_array”

FIGURE 14: CONVENTION USED FOR THE STD_TABLE TYPE

state_type: User-defined generic type

o Defines the state names used for the finite state machine.

Page 27: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

20 ttt: Overall Design

sg ai_try_direct

hp_move ai_random

status ai_status

ai_try_win loss

ai_try_block tie

ai_try_fork win

ai_try_blockfork FIGURE 15: TABLE OF ALL STATE NAMES DEFINED BY THE CUSTOM_TYPES PACKAGE

TTT: OVERALL DESIGN

DESCRIPTION

This circuit is the top level entity of the project. It basically groups all components of the circuit

in a single vhdl file and manages the inputs and outputs with the outside world.

By observing the code, one can see that the circuit basically assigns the correct signal lines to

each component of the tic-tac-toe game. The input signals (in the entity) are those which the

user can directly control using the Altera Board (Except “clk”). The outputs “hex0_out”,

“hex1_out”, “hex2_out” and “hex3_out” are information for LED display and the signal

“state_out” is information for the red light led displays.

The components ‘g27_control’, ‘g27_ga_array’, ‘g27_gm_led’, ‘g27_hp_wait’,

‘g27_sys_led_state’ all follow the clock; the components ‘g27_ga_array_mux’,

‘g27_gm_status’, ‘g27_ai_find_win’, ‘g27_ai_fork’, ‘g27_ai_block_fork’, ‘g27_ai_direct_write’,

‘g27_ai_random’ are dependent only on changes of “curr_state” signal. Note: though some

components do not follow the clock explicitly, the current state does depend on the clock.

DESCRIPTION OF THE I/O PINS

The “ai_fork” component has exactly the same pin configuration as the “ai_try_win”

component (as do all the components handling the AI strategy).

Input Pins:

clk: std_logic

Page 28: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

21 ttt: Overall Design

o Clock of the circuit

reset: std_logic

o if high, nothing | if low, clear all signals and GA array

user_start: std_logic

o if low, HP starts game | if high, AI starts game

user_row: std_logic_vector(1 downto 0)

o row coordinate inputted by HP]

user_col: std_logic_vector(1 downto 0)

o col coordinate inputted by HP

user_set: std_logic

o when low, game assumes HP coordinates are ready

o when high, the circuit hold its state

user_toggle_marks: std_logic

o if low, show ‘O’ marks | if high, show ‘X’ marks

user_show_array: std_logic

o Force the GA array to be displayed on LED no matter the state

user_lvl: std_logic_vector(1 downto 0)

o level of difficulties: ‘00’=1, ‘01’=2, ‘10’=3, ‘11’=4

user_begin: std_logic

o if low, user acknowledges the beginning of the game

Output Pins:

hex0_out: std_logic_vector(0 to 6)

o 2nd rightmost LED unit

hex2_out: std_logic_vector(0 to 6

o 2nd leftmost LED unit

hex3_out: std_logic_vector(0 to 6)

o leftmost LED unit

state_out: std_logic_vector(9 downto 0)

o red light LED display

Page 29: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

22 ttt: Overall Design

FIGURE 16: BLOCK DIAGRAM OF THE TTT COMPONENT

PIN ASSIGNMENTS

Input pins:

Signal Assigned Pin

clk PIN_D12

reset PIN_T21

user_begin PIN_M22

user_col[1] PIN_M2

user_col[0] PIN_U11

user_lvl[1] PIN_L21

user_lvl[0] PIN_L22

user_row[1] PIN_L2

user_row[0] PIN_M1

user_set PIN_R21

user_show_array PIN_R22

user_start PIN_T22

user_toggle_marks PIN_U12

FIGURE 17: INPUT PIN ASSIGNMENTS FOR G27_TTT.VHD

Output pins:

Signal Assigned Pin

hex0_out[0] PIN_J2

hex0_out[1] PIN_J1

hex0_out[2] PIN_H2

hex0_out[3] PIN_H1

Signal Assigned Pin

hex0_out[4] PIN_F2

hex0_out[5] PIN_F1

hex0_out[6] PIN_E2

hex1_out[0] PIN_E1

Page 30: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

23 ttt: Overall Design

Signal Assigned Pin

hex1_out[1] PIN_H6

hex1_out[2] PIN_H5

hex1_out[3] PIN_H4

hex1_out[4] PIN_G3

hex1_out[5] PIN_D2

hex1_out[6] PIN_D1

hex2_out[0] PIN_G5

hex2_out[1] PIN_G6

hex2_out[2] PIN_C2

hex2_out[3] PIN_C1

hex2_out[4] PIN_E3

hex2_out[5] PIN_E4

hex2_out[6] PIN_D3

hex3_out[0] PIN_F4

hex3_out[1] PIN_D5

hex3_out[2] PIN_D6

Signal Assigned Pin

hex3_out[3] PIN_J4

hex3_out[4] PIN_L8

hex3_out[5] PIN_F3

hex3_out[6] PIN_D4

state_out[9] PIN_R17

state_out[8] PIN_R18

state_out[7] PIN_U18

state_out[6] PIN_Y18

state_out[5] PIN_V19

state_out[4] PIN_T18

state_out[3] PIN_Y19

state_out[2] PIN_U19

state_out[1] PIN_R19

state_out[0] PIN_R20

FIGURE 18: INPUT PIN ASSIGNMENTS FOR

G27_TTT.VHD

REPORTS

g27_control.vhd

Total logic elements 508 / 18,752 ( 3 % )

Total combinational functions 498 / 18,752 ( 3 % )

Dedicated logic registers 97 / 18,752 ( < 1 % )

Total registers 97

Total pins 51 / 315 ( 16 % ) FIGURE 19: FLOW SUMMARY FOR G27_TTT.VHD

Component LC Combinationals LC

Registers

|g27_ai_block_fork:ai_block_fork| 38 0

|g27_ai_direct_write:ai_direct_write| 8 0

|g27_ai_find_win:ai_find_win| 53 0

|g27_ai_fork:ai_fork| 98 0

|g27_ai_random:ai_random| 7 0

|g27_control:control| 25 13

|g27_ga_array:ga_array| 29 18

|g27_ga_array_mux:ga_array_mux| 80 0

|g27_gm_led:gm_led| 83 51

|g27_gm_status:gm_status| 50 0

|g27_hp_wait:hp_wait| 19 5

Page 31: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

24 ttt: Overall Design

|g27_sys_led_state:sys_led_state| 8 10

Total (g27_ttt) 498 97 FIGURE 20: RESOURCE UTILISATION BY ENTITY

Type Slack Time From To

Worst-case tsu

8.021 ns user_show_array g27_gm_led:gm_led|hex2_o

ut[2]

Worst-case tco

11.521 ns g27_gm_led:gm_led|hex3_o

ut[6] hex3_out[6]

Worst-case th

0.494 ns user_lvl[1] g27_gm_led:gm_led|hex0_o

ut[5]

Clock Setup: 'clk'

29.169 ns

80.02 MHz ( period =

12.497 ns )

g27_ga_array:ga_array|ga_array[1][2][1]

g27_ga_array:ga_array|ga_array[0][1][0]

Clock Hold: 'clk'

0.445 ns

N/A g27_control:control|fstate.ti

e g27_control:control|fstate.ti

e FIGURE 21: TIMING ANALYSIS SUMMARY

SIMULATIONS AND WAVEFORMS

Since describing all the control lines is excessively troublesome, we will only demonstrate the

functionality of this circuit by performing a simulation of a game. To allow better

understanding of the output signals, here is a list of states associated with their corresponding

“state_out” value:

sg => "1000000000";

hp_move => "0100000000";

status => "0010000000";

ai_try_win => "0001000000";

ai_try_block => "0000100000";

ai_try_fork => "0000010000";

ai_try_blockfork => "0000001000";

ai_try_direct => "0000000100";

loss => "0000000010";

win => "0000000001";

tie => "0000000011";

ai_random => "0001111100";

Page 32: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

25 ttt: Overall Design

ai_status => "1110000000";

The following is a waveform of the start of the game, which was used during the demo. The

full game is presented in the waveform file g27_ttt.vwf.

FIGURE 22: OVERALL SIMULATION OF THE GAME

Note that the input signals are active low. We chose level 4 (“user_lvl” = ‘11’ = 3), which means

the AI will toggle between offense and defense accordingly while being able to deal with and

perform forks. Notice that the output “state_out” always follow the present state of the game,

and if compared to the list presented above, one should see that they are correct. The LED

display are explained in g27_gm_led.vhd section, with the left most LED unit corresponding to

the value of “hex3_out” output. “hex1_out”, “hex2_out” and “hex3_out” are used to display

the game using their horizontal bars (which coincidentally have a 3 by 3 mapping, perfect for

displaying the game.) “hex4_out” is used to display which of the two marks (‘X’ or ‘O’) is

currently displayed, which is determined by the signal “user_toggle_marks” (if high, mark = ‘X’

| if low, mark = ‘O’). The toggle mark function is demonstrated at the end of the first cycle of

the game, where the LED display suddenly changed to display the only ‘X’ mark on the field

when the signal “user_toggle_marks” is set to high. After the first cycle through the states, the

Page 33: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

26 ttt: Overall Design

AI added its move to the game board, which is displayed on the LED at the correct position,

and the circuit is on hold until the next cycle begins when the player inserts his/her next mark.

The end result of the game is in the state ‘tie’. This simulation simply shows that the circuit

does perform the tic-tac-toe game provided that the user continuously feed legal coordinates

for the ‘X’ marks.

FIGURE 23: EXCEPTIONAL CASE HANDLING IN THE GAME

In the second waveform (g27_ttt2.vwf), notice that the circuit will be stuck at the state

‘hp_move’ as long as the “r_c” signal gives an illegal coordinate where there already was an

inserted mark. In the first case, the coordinate is in the center of the field, where the HP

already inserted an ‘X’ mark. In the second case, the coordinate correspond to the lower left

corner cell, where the AI has already inserted an ‘O’ mark. After that, the signal “reset” has

Page 34: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

27 sys_led_state: LED Current State Display

been set to low, thus clearing the entire GA array, allowing the states to flow until the circuit

attempt to insert a mark at an already taken position. The circuit is put on hold afterward.

SYS_LED_STATE: LED CURRENT STATE DISPLAY

DESCRIPTION

This circuit’s job is to send out the right signal for the red led lights to represent the right

current state in the FSM. By looking at which red LED light is on and off, the user can

determine the present state of the game. This is a component we used to debug the finite

state machine and decided to keep in our overall design. The circuit simply looks at the current

state at every clock cycle and outputs the state represented by the LED lights. Each state is

assigned a unique pattern by which the 9 red led lights will shine to indicate them. The reader

can easily see this by directly looking at the code.

DESCRIPTION OF THE I/O PINS

Input Pins:

clk: std_logic

o The clock, generated by the 24MHz Oscillator on the Altera board

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

Output Pins:

state_out: std_logic_vector(9 downto 0)

o Outputted towards the board’s pins

o Binary representation for the red led lights

Page 35: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

28 sys_led_state: LED Current State Display

FIGURE 24: BLOCK DIAGRAM OF THE SYS_LED_STATE COMPONENT

SIMULATIONS AND WAVEFORMS

The following waveform (g27_sys_led_state1) demonstrates the output “state_out” which has

a different binary number for each possible state.

PSEUDOCODE

if(rising_edge(clk)){ switch(curr_state){ case sg: state_out = "1000000000"; case hp_move: state_out = "0100000000"; case status: state_out = "0010000000"; case ai_try_win: state_out = "0001000000"; case ai_try_block: state_out = "0000100000"; case ai_try_fork: state_out = "0000010000"; case ai_try_blockfork: state_out = "0000001000"; case ai_try_direct: state_out = "0000000100"; case loss: state_out = "0000000010"; case win: state_out = "0000000001";

Page 36: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

29 sys_led_state: LED Current State Display

case tie: state_out = "0000000011"; case ai_random: state_out = "0001111100"; case ai_status: state_out = "1110000000"; } }

GM_LED: SEVEN SEGMENT LED DISPLAY

DESCRIPTION

This circuit’s job is to display the tic-tac-toe 3 by 3 board, the statuses of the game, the level of

difficulty and the whereabouts of the HP next move. The game itself is displayed using the

horizontal bars of the LEDs since we have 3 bars per column and we have 4 bars width, which is

sufficient to display the game.

The information displayed on the LED depends on the current state of the game (“curr_state”).

For example, if “curr_state” = win, the LED will display the word ‘FAIL’ to indicate that the AI

won the game. There is a set of priority on the states to determine the message from to which

state will be displayed , and is in the following descending order: ‘win’, ‘loss’, ‘tie’, ‘sg’, and the

rest are equivalent (except ‘hp_move’).

When the current state is ‘loss’, the word ‘win’ will be displayed.

When the current state is ‘tie’, the word ‘tie’ will be displayed.

When the current state is ‘sg’, the symbol ‘lvl’ will be displayed on the left followed by

an integer of 1 to 4 depending on the signal “level” (“level”: ‘00’ = 1, ‘01’= 2, ‘10’=3,

‘11’=4).

When the current state is anything else, the LED display the position of all target marks

on the field (‘X’ if “mark_x_en” = ‘01’, ‘O’ if “mark_x_en” = ‘11’)

When the current state is ‘hp_move’, the LED will not only perform the task described

in the bullet right above, but will also display the current position the HP is about to

insert his/her next mark (“user_curr_row”, “user_curr_col”). Note that this position will

Page 37: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

30 sys_led_state: LED Current State Display

be displayed as a dim light bar (LED used only once per 15 clock cycle) no matter the

value of “mark_x_en”.

To finish, when the signal “show_array_n” = 0, the circuit will bypass the states ‘win’, ‘loss’, ‘tie’

and ‘sg’ and directly show the present situation of the game by displaying the marks. This

allows the HP to view the game board even if the current state is win, loss, or tie.

DESCRIPTION OF THE I/O PINS

Input Pins:

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

ga_array_in: std_table

o Outputted by the “ga_array” component

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

show_array_n: std_logic

o User input

o This signal forces the LED to display the GA array when low

mark_x_en: std_logic

o User input

o If signal = ‘11’, only ‘O’ marks will be displayed; if signal = ‘01’, then only ‘X’

marks will be displayed.

level: std_logic_vector(1 downto 0)

o User input

o The level of AI difficulty from 1 to 4 (‘00’ to ‘11’)

user_curr_row: in std_logic_vector(1 downto 0)

Page 38: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

31 sys_led_state: LED Current State Display

o User input

o The row coordinate the HP is currently selecting

user_curr_col: in std_logic_vector(1 downto 0))

o User input

o The column coordinate the HP is currently selecting

Output Pins:

hex0_out: std_logic_vector(0 to 6)

hex1_out: std_logic_vector(0 to 6)

hex2_out: std_logic_vector(0 to 6)

hex3_out: std_logic_vector(0 to 6)

o All output to the board through the seven segment display.

o 7-bit representation of each of the four hex-displays on the Altera board

FIGURE 25: BLOCK DIAGRAM OF THE GM_LED COMPONENT

SIMULATIONS AND WAVEFORMS

The following waveform (g27_gm_led1) demonstrate the cases for the states ‘win’, ‘loss’, ‘tie’

and ‘sg’. On the image presented on top of the waveform is an index map of a single LED

display unit to the 7 bits of the “hex_out” output, from 6 at left to 0 on the right. Using the

output of the waveform, one can determine that the outputs correspond to the correct result

for each state.

Page 39: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

32 sys_led_state: LED Current State Display

FIGURE 26: BIT ASSIGNMENT FOR THE SEVEN-SEGMENT DISPLAY

FIGURE 27: INITIAL SIMULATIONS OF THE GM_LED COMPONENT

The next waveform (g27_gm_led2) tests the case when the remaining states. If one maps the

outputs correctly, it can be seen that the outputs represent the positions of the marks of the

selected type (depending on “mark_x_en”).

Page 40: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

33 sys_led_state: LED Current State Display

FIGURE 28: SIMULATION OF THE GM_LED COMPONENT THROUGH MULTIPLE STATES

The third waveform (g27_gm_led3) simply shows the state of ‘hp_move’ where the LED only

display once per 15 clock cycles.

Page 41: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

34 sys_led_state: LED Current State Display

FIGURE 29: FINAL SIMULATION OF THE GM_LED COMPONENT TESTING THE DIMMING

PSEUDOCODE

if(rising_edge(CLK)){ hex0= "1111111"; hex1= "1111111"; hex2= "1111111"; hex3= "1111111"; // TODO: Change all inputs to 1 when done testing if(curr_state == win and show_array_n == '1'){ // Spell: Fail hex3= "0111000"; hex2= "0001000"; hex1= "1001111"; hex0= "1110001"; } else if(curr_state == loss and show_array_n == '1'){ // Spell: |_._| | .-. hex3= "1100001"; hex2= "1000011"; hex1= "1001111";

Page 42: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

35 sys_led_state: LED Current State Display

hex0= "1101010"; } else if(curr_state == tie and show_array_n == '1'){ // Spell: Tie hex3= "1110000"; hex2= "1001111"; hex1= "0110000"; } else if(curr_state == sg){ // Spell: lvl # hex3= "1110001"; hex2= "1100011"; hex1= "1110001"; switch(level){ case "00" : hex0 = "1001111"; case "01" : hex0 = "0010010"; case "10" : hex0 = "0000110"; case default : hex0 = "1001100"; } }else { // In HEX0, show "X" if the user_toggle_marks switch is high // Also, set mark to "01" so that only "X" marks are shown when this is the case if(mark_x_en == '1'){ mark= "01"; hex0= "1001000"; }else { // In HEX0, show "O" if the user_toggle_marks switch is low // Also, set mark to "11" so that only "O" marks are shown when this is the case mark= "11"; hex0= "0000001"; } // If the content of a cell in the game array is the current MARK (as specified above) //{ light up the corresponding LED on the hex display if(ga_array_in(0,0) == mark or (user_curr_row == "00" and user_curr_col == "00" and light == '1'))then hex3(3)= '0'; } if(ga_array_in(1,0) == mark or (user_curr_row == "01" and user_curr_col == "00" and light == '1')){ hex3(6)= '0'; } if(ga_array_in(2,0) == mark or (user_curr_row == "10" and user_curr_col == "00" and light == '1'))then hex3(0)= '0'; } if(ga_array_in(0,1) == mark or (user_curr_row == "00" and user_curr_col == "01" and light == '1'))then hex2(3)= '0'; }

Page 43: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

36 ga_array: Game Table

if(ga_array_in(1,1) == mark or (user_curr_row == "01" and user_curr_col == "01" and light == '1'))then hex2(6)= '0'; } if(ga_array_in(2,1) == mark or (user_curr_row == "10" and user_curr_col == "01" and light == '1')){ hex2(0)= '0'; } if(ga_array_in(0,2) == mark or (user_curr_row == "00" and user_curr_col == "10" and light == '1'))then hex1(3)= '0'; } if(ga_array_in(1,2) == mark or (user_curr_row == "01" and user_curr_col == "10" and light == '1'))then hex1(6)= '0'; } if(ga_array_in(2,2) == mark or (user_curr_row == "10" and user_curr_col == "10" and light == '1'))then hex1(0)= '0'; } } if(curr_state == hp_move){ if(count == 15){ count = 0; light = '1'; }else { count = count + 1; light = '0'; } }else { light = '0'; } // Pass final values of the hex display to the output hex0_out = hex0; hex1_out = hex1; hex2_out = hex2; hex3_out = hex3; }

GA_ARRAY: GAME TABLE

DESCRIPTION

Page 44: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

37 ga_array: Game Table

The GA array circuit’s job is simply updating any inputs from either the AI player or HP when

called upon (“write_en” = 1) into the GA array. It also will clear the entire game board when

necessary (when game starts or resets).

This circuit activates only on the rising edges of the clock. In each clock cycle, it keeps track of

the signals “clear” and “write_en”.

When “clear” = 1, the GA’s cells will all be emptied (reset).

When “write_en” = 1, the circuit will insert the desired mark according to the value of the signal

“mark_type” (‘10’ = ‘X’, ‘11’ = ‘O’) at the coordinates given by “row_id” and “col_id”.

No matter what happens, the GA array will be updated through the output signal

“ga_array_out” at each clock cycle (even if no change was made in the table).

Note: it is assumed that the coordinates provided by “row_id” and “col_id” would lead to a free

cell where a new mark can be inserted without erasing any previous inhabitant. These two

signals are verified beforehand by other components.

DESCRIPTION OF THE I/O PINS

Input Pins:

clk: std_logic

o The clock, generated by the 24MHz Oscillator on the Altera board

clear: std_logic

o Generated by the “ga_array_mux” component

o if “clear” = 1, GA array is emptied, i.e. all its contents are set to “00”

write_en: std_logic

o Generated by the “ga_array_mux” component

o if “write_en” = 1, the a mark of type “mark_type” will be inserted at coordinate

“row_id”, “col_id”

mark_type: std_logic_vector(1 downto 0)

o Generated by the “ga_array_mux” component

Page 45: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

38 ga_array: Game Table

o ‘11’ = ‘O’ mark; ‘10’ = ‘X’ mark

row_id: integer range 0 to 2

o Generated by the “ga_array_mux” component

o The row index of the newly inserted “X” mark

col_id: integer range 0 to 2

o Generated by the “ga_array_mux” component

o The column index of the newly inserted “X” mark

Output Pins:

ga_array_out: std_table

o Outputted to all components

o Representation of the current state of the game table

FIGURE 30: BLOCK DIAGRAM OF THE GA_ARRAY COMPONENT

SIMULATIONS AND WAVEFORMS

The waveform presented below shows some cases of inserted marks, with the “clear”=1 case in

the middle. As was assumed, the circuit fill out the array at the correct coordinates presented

by “row_id” and “col_id” with the correct “mark_type”. The circuit also clears the entire array

when “clear”=1.

Page 46: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

39 ga_array_mux: Multiplexer for the Game Table

FIGURE 31: SIMULATION WAVEFORM FOR THE GA_ARRAY COMPONENT

PSEUDOCODE

if(rising_edge(CLK)){ if (clear = 1) { ga_array = ((0,0,0),(0,0,0),(0,0,0)); } if (write_en = 1){ ga_array(row_id, col_id) = mark_type; } }

GA_ARRAY_MUX: MULTIPLEXER FOR THE GAME TABLE

DESCRIPTION

This circuit’s job is assigning the correct command signals and correct mark to the right

coordinates of the next cell to be filled depending on the present state. This circuit will check

the present state at each clock cycle and send the appropriate signals to the ga_array circuit.

Depending on the value of the signal “curr_state”, this circuit decides whether to clear the GA

array (clear_out) or to insert a mark (“mark_type_out”) when needed (“enable_out”) at the

correct coordinates in the GA array (“col_id” & “row_id”). The output signal “mark_type_out”

depends if the current state belong to the HP or AI (mark = “11” if AI, mark = “10” if HP). If the

current state is ‘hp_move’ and the HP has made his move (“hp_mademove” = 1), the “row_id”

and “col_id” will correspond to the coordinates inputted by HP. If the current state belongs to

one of the AI states (‘ai_try_win’, ’ai_try_block’, ‘ai_try_fork’, ‘ai_try_blockfork’, ‘ai_try_direct’,

’ai_random’), the circuit must choose between various coordinate input signal lines depending

on which of the various AI states the present state is. As an example, if the “curr_state” =

‘ai_try_fork’, the circuit will pass the ga_array component the coordinates generated by the

component ai_fork (“row_id_ai_fork”, “col_id_ai_fork”) and the enable signal “ai_fork_en”. If

Page 47: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

40 ga_array_mux: Multiplexer for the Game Table

“curr_state” = ‘sg’, the clear signal will be sent to ga_array component and the GA array will be

cleared.

DESCRIPTION OF THE I/O PINS

Input Pins:

clk: std_logic

o The clock, generated by the 24MHz Oscillator on the Altera board

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

row_id_hp_wait : integer range 0 to 2

o row coordinate generated by the “hp_wait” component

col_id_hp_wait : integer range 0 to 2

o column coordinate generated by HP]

hp_mademove : std_logic

o enable “write_en” of “ga_array” component only when the HP made a move

row_id_ai_find_win : integer range 0 to 2

o row coordinate generated by “ai_find_win” component

col_id_ai_find_win : integer range 0 to 2

o col coordinate generated by “ai_find_win” component

ai_find_win_en : std_logic

o enable signal generated by “ai_find_win” component

row_id_ai_fork : integer range 0 to 2

Page 48: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

41 ga_array_mux: Multiplexer for the Game Table

o row coordinate generated by “ai_fork” component

col_id_ai_fork : integer range 0 to 2

o col coordinate generated by “ai_fork” component

ai_fork_en : std_logic

o enable signal generated by “ai_fork” component

row_id_ai_blockfork : integer range 0 to 2

o row coordinate generated by “ai_block_fork” component

col_id_ai_blockfork : integer range 0 to 2

o col coordinate generated by “ai_block_fork” component

ai_blockfork_en : std_logic

o enable signal generated by “ai_block_fork” component

row_id_ai_direct_write : integer range 0 to 2

o row coordinate generated by “ai_random” component

col_id_ai_direct_write : integer range 0 to 2

o col coordinate generated by “ai_random” component

ai_direct_write_en : std_logic

o enable signal generated by “ai_random” component

mark_type: std_logic_vector(1 downto 0)

o Generated by the “ga_array_mux” component

o ‘11’ = ‘O’ mark; ‘10’ = ‘X’ mark

Output Pins:

row_id: integer range 0 to 2

o The row index of the newly inserted “X” mark

col_id: integer range 0 to 2

o The column index of the newly inserted “X” mark

Page 49: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

42 ga_array_mux: Multiplexer for the Game Table

enable_out: std_logic

o outputted enable signal

clear_out: std_logic

o outputted clear signal

mark_type_out: std_logic_vector(1 downto 0)

o outputted mark type

FIGURE 32: BLOCK DIAGRAM OF THE GA_ARRAY_MUX COMPONENT

SIMULATIONS AND WAVEFORMS

The following waveform present cases of each state “curr_state” and the various consequences

on the signals generated. The coordinates from each AI components are different from each

other, thus allowing them to be identified at the output signals. By observing the waveform,

one can determine that during the clock cycle of each state, their corresponding value of

coordinates passed on to the output signals. The “mark_type_out” is 1 when in HP state and 3

Page 50: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

43 ga_array_mux: Multiplexer for the Game Table

when in AI states. The “enable_out” signal is high when in HP and AI states and only drops at

‘sg’ state where the signal “clear_out” = 1. Note that the state ‘ai_random’ is equivalent to

‘ai_try_direct’, and is not considered.

FIGURE 33: SIMULATION WAVEFORM FOR THE GA_ARRAY_MUX COMPONENT

PSEUDOCODE

if( hp_move ){

Page 51: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

44 gm_status: Check Current Game Status

row_id = row_id_hp_wait; col_id = col_id_hp_wait; enable = hp_mademove; clear = 0; mark_type = 01; }if( ai_try_win ){ row_id = row_id_ai_find_win; col_id = col_id_ai_find_win; enable = ai_find_win_en; clear = 0; mark_type = 11; }if( ai_try_block ){ row_id = row_id_ai_find_win; col_id = col_id_ai_find_win; enable = ai_find_win_en; clear = 0; mark_type = 11; }if( ai_try_fork ){ row_id = row_id_ai_fork; col_id = col_id_ai_fork; enable = ai_fork_en; clear = 0; mark_type = 11; }if( ai_try_blockfork ){ row_id = row_id_ai_blockfork; col_id = col_id_ai_blockfork; enable = ai_blockfork_en; clear = 0; mark_type = 11; }if( ai_try_direct ){ row_id = row_id_ai_direct_write; col_id = col_id_ai_direct_write; enable = ai_direct_write_en; clear = 0; mark_type = 11; }if( sg ){ row_id = 0; col_id = 0; enable = 0; clear = '1'; mark_type = 11; }if( others ){ row_id = 0; col_id = 0; enable = 0; clear = 0; }

GM_STATUS: CHECK CURRENT GAME STATUS

DESCRIPTION

Page 52: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

45 gm_status: Check Current Game Status

This circuit’s job is to determine the current status of the game, that is, whether the game has

ended in a win, loss or a tie, or the game is still not complete.

Status determination only occurs at state ‘status’ or ‘ai_status’. To determine a win (for the

AI), the circuit simply checks all possible row combinations in the game to see if a row is filled

by ‘O’ or ‘X’ marks (if “curr_state” = ‘status’, ‘X’ marks will be checked, otherwise, ‘O’ marks will

be checked). A tie occurs when no such row has been detected and there is no empty cell left

in GA array. If no row is complete and free cells are still available, the game is incomplete (all 3

outputs low).

DESCRIPTION OF THE I/O PINS

Input Pins:

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

ga_array_in: std_table

o Outputted by the “ga_array” component

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

Output Pins:

gm_loss: std_logic

o Outputted towards the controller “control”

o High if AI loss is detected, low otherwise

gm_tie: std_logic

o Outputted towards the controller “control”

o High if a finished tie game is detected, low otherwise

Page 53: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

46 gm_status: Check Current Game Status

gm_win: std_logic

o Outputted towards the controller “control”

o High if AI win is detected, low otherwise

FIGURE 34: BLOCK DIAGRAM OF THE GM_STATUS COMPONENT

SIMULATIONS AND WAVEFORMS

The following is a waveform (g27_gm_status1) showing the four situations: win, loss, tie,

incomplete.

The code is simple enough so one can assume the other cases would work as well.

FIGURE 35: SIMULATION WAVEFORM FOR THE GM_STATUS COMPONENT

PSEUDOCODE

if(curr_state == status or curr_state == ai_status){ if(curr_state == status){ mark= "01"; }else { mark= "11"; } // if there exists a completed row full of "X" marks, then the HP has won if (ga_array_in(0,0) == mark AND ga_array_in(0,1) == mark AND ga_array_in(0,2) == mark) OR (ga_array_in(1,0) == mark AND ga_array_in(1,1) == mark AND ga_array_in(1,2) == mark) OR (ga_array_in(2,0) == mark AND ga_array_in(2,1) == mark AND ga_array_in(2,2) == mark) OR

Page 54: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

47 hp_wait: Wait for HP Move

(ga_array_in(0,0) == mark AND ga_array_in(1,0) == mark AND ga_array_in(2,0) == mark) OR (ga_array_in(0,1) == mark AND ga_array_in(1,1) == mark AND ga_array_in(2,1) == mark) OR (ga_array_in(0,2) == mark AND ga_array_in(1,2) == mark AND ga_array_in(2,2) == mark) OR (ga_array_in(0,0) == mark AND ga_array_in(1,1) == mark AND ga_array_in(2,2) == mark) OR (ga_array_in(0,2) == mark AND ga_array_in(1,1) == mark AND ga_array_in(2,0) == mark){ if(curr_state == status){ gm_loss = '1'; gm_tie = '0'; gm_win = '0'; }else { gm_loss = '0'; gm_tie = '0'; gm_win = '1'; } } else if(ga_array_in(0,0)(0) == '1' AND ga_array_in(0,1)(0) == '1' AND ga_array_in(0,2)(0) == '1' )AND (ga_array_in(1,0)(0) == '1' AND ga_array_in(1,1)(0) == '1' AND ga_array_in(1,2)(0) == '1') AND (ga_array_in(2,0)(0) == '1' AND ga_array_in(2,1)(0) == '1' AND ga_array_in(2,2)(0) == '1') AND (ga_array_in(0,0)(0) == '1' AND ga_array_in(1,0)(0) == '1' AND ga_array_in(2,0)(0) == '1') AND (ga_array_in(0,1)(0) == '1' AND ga_array_in(1,1)(0) == '1' AND ga_array_in(2,1)(0) == '1') AND (ga_array_in(0,2)(0) == '1' AND ga_array_in(1,2)(0) == '1' AND ga_array_in(2,2)(0) == '1') AND (ga_array_in(0,0)(0) == '1' AND ga_array_in(1,1)(0) == '1' AND ga_array_in(2,2)(0) == '1') AND (ga_array_in(0,2)(0) == '1' AND ga_array_in(1,1)(0) == '1' AND ga_array_in(2,0)(0) == '1'){ gm_loss = '0'; gm_tie = '1'; gm_win = '0'; }else { gm_loss = '0'; gm_tie = '0'; gm_win = '0'; } }else { gm_loss = '0'; gm_tie = '0'; gm_win = '0'; }

HP_WAIT: WAIT FOR HP MOVE

Page 55: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

48 hp_wait: Wait for HP Move

DESCRIPTION

The “hp_wait” component is responsible for the capture of the human player’s moves. As such,

it is active only during the “hp_move” state. At every rising edge of the clock, the component

checks if the user has pressed the “set” button, indicating that the human player wishes to add

an “X” mark to the game table “ga_array” in the user-specified row “row_id” and the column

“col_id”. If the location desired is invalid (“row_id” = “11” or “col_id” = “11”) or if it is non-empty

(i.e. “ga_array[row_id][col_id]” has non-zero value), then nothing happens as the output

control signal “hp_mademove” is set to ‘0’ to indicate that the human player has not made a

move yet. If the location specified is empty, then the row and column indices are passed on to

their corresponding outputs and “hp_mademove” is set to ‘1’ to show that the human player

has made a move.

DESCRIPTION OF THE I/O PINS

Input Pins:

clk: std_logic

o The clock, generated by the 24MHz Oscillator on the Altera board

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

ga_array_in: std_table

o Outputted by the “ga_array” component

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

set: std_logic

o User input (push button)

o Indicates that the human player wants to make a move (active low)

hp_row_in: std_logic_vector(1 downto 0)

o User input (push button)

Page 56: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

49 hp_wait: Wait for HP Move

o 2-bit representation of the currently selected row by the user

hp_col_in: std_logic_vector(1 downto 0)

o User input (push button)

o 2-bit representation of the currently selected column by the user

Output Pins:

row_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The row index of the newly inserted “X” mark

col_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The column index of the newly inserted “X” mark

hp_mademove: std_logic

o Outputted towards the game table component “ga_array”

o Indicates that the human player has successfully made a move

FIGURE 36: BLOCK DIAGRAM OF THE HP_WAIT COMPONENT

SIMULATIONS AND WAVEFORMS

To test the functionality of the hp_wait component, we made a simple test covering each case

we are interested in. The results are shown in the waveform below. In this test, the user tries to

set an “X” mark in the game table at row 2, column 1 in a table where the cell at that position is

empty initially.

Page 57: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

50 hp_wait: Wait for HP Move

During the first two clock cycles, the user tries to set an “X” mark when the current state of the

finite state machine is still not “hp_move”. As such, the output “hp_mademove” is not set to ‘1’

and as such the state remains “hp_move”.

In the third clock cycle, we check what happens if the user does not press on the set button,

that is, the “set” signal is set to ‘1’. As expected, the “hp_mademove” signal remains at ‘0’.

In the fourth clock cycle, we simulate the user pressing the button by setting the “set” input to

“0”. Finally, the “hp_mademove” signal is set to ‘1’ with correct “row_id” and “col_id”,

indicating that the user has made a move to place an “X” in the location specified by the row

and column indices.

In the fifth clock cycle, we update the game table by giving a value of 1 to the cell at row 2 and

column 1. The “hp_mademove” then is set to ‘0’ since the component detects that the location

specified is non-empty.

Finally, in the sixth clock cycle, the user inputs an invalid location: row “11” and column “01”.

The function detects this, and still does not indicate a human player move.

FIGURE 37: SIMULATION WAVEFORM OF THE HP_WAIT COMPONENT

PSEUDOCODE

if (curr_state == hp_move){ made_move = '0'; // If the inputs for row and col id are valid // (i.e. they can only have value 00, 01 or 10) // then if the user has the set button pressed, // add an "X" mark to the row and column specified in the ga_array

Page 58: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

51 ai_find_win: Try to Win Or Block

if (hp_row_in != "11" and hp_col_in != "11"){ if (set == '0'){ if (ga_array_in(row, col) == "00"){ // If the enter button is pressed, check to see if // the cell can be written to // If it can, add x to ga_array row_id = row; col_id = col; made_move = '1'; } } } }else { made_move = '0'; } hp_mademove = made_move;

AI_FIND_WIN: TRY TO WIN OR BLOCK

DESCRIPTION

The “ai_find_win” component is responsible for two parts of the AI’s playing strategy, which

are independently called based on the current state of the finite state machine in the

controller.

During the “ai_try_win” state, the AI checks the game table “ga_array_in” to see if it can win in

his current turn. The pattern is trivial: any horizontal, vertical or diagonal row that contains two

“O” marks (value “11”) and one empty space (value “00”) is a potential winning row. When such

a row is found, the component outputs the row index “row_id” and column index “col_id” of

the empty cell, filling the row with three “O” marks and hence winning the game. It also sets

the control signal “ai_mademove” to ‘1’ to signal that the AI is making a move. If no nearly

complete row is found, “ai_mademove” is set to ‘0’ and the controller changes to its next

strategy state on the next clock cycle.

During the “ai_try_block” state, the AI checks “ga_array_in” to stop the human from making a

winning move in his next turn. In this state, we look for the same pattern as above, except we

look for rows containing “X” marks (value “01”) instead of “O” marks. When a good row is

found, the component outputs the row index “row_id” and column index “col_id” of the empty

Page 59: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

52 ai_find_win: Try to Win Or Block

cell, blcoking the row with the “O” mark and hence preventing a human player win. It also sets

the control signal “ai_mademove” to ‘1’ to signal that the AI is making a move. If no nearly

complete row of “X” marks is found, “ai_mademove” is set to ‘0’ and the controller changes to

its next strategy state on the next clock cycle.

DESCRIPTION OF THE I/O PINS

Input Pins:

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

ga_array_in: std_table

o Outputted by the “ga_array” component

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

Output Pins:

row_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The row index of the newly inserted “X” mark

col_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The column index of the newly inserted “X” mark

ai_mademove: std_logic

o Outputted towards the game table component “ga_array”

o Indicates that the AI has successfully made a move

Page 60: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

53 ai_find_win: Try to Win Or Block

FIGURE 38: BLOCK DIAGRAM OF THE AI_FIND_WIN COMPONENT

SIMULATIONS AND WAVEFORMS

We did a few simulations to see if the “ai_find_win” component works as intended.

First, we made sure that all possible winning rows can be detected and that the empty cell that

needs to be filled so that the row becomes complete or is blocked. In the waveform below, we

set the state to be “ai_try_win”) and tested the case of horizontal rows, then vertical rows,

then finally diagonal rows. Upon inspection of the outputs “row_id” and “col_id” with the

location of the empty cell to be filled, we confirm that all possible row completions can be

detected. Also, the output signal “ai_mademove” is set at “1” after each try, showing that the

AI has made its move through the “ai_find_win” component.

FIGURE 39: WAVEFORM OF AI_FIND_WIN COVERING ALL POSSIBLE WINNING ROWS

In the next waveform, we do the same simulation as before, except we replace all “O” marks

(‘”00”) with “X” marks and set the state to “ai_try_block”. This way, the AI will add the “O”

Page 61: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

54 ai_find_win: Try to Win Or Block

mark in the same places specified in the first waveform, this time to block an impending win by

the human player.

FIGURE 40: WAVEFORM OF AI_FIND_WIN COVERING ALL POSSIBLE LOSING ROWS

Finally, we check that the component works correctly when no valid rows are detected. In the

waveform below, we cover the cases where the number of “X” marks in a row is 0, 1 and 2. In

the last case (2 “X” marks), the last element of the row is an “O” mark. In all cases, nothing will

happen as the output signal “ai_mademove” remains at ‘0’.

FIGURE 41: WAVEFORM OF AI_FIND_WIN COVERING INVALID ROWS

PSEUDOCODE

if (curr_state == ai_try_win or curr_state == ai_try_block){ row_id_temp= 0; col_id_temp= 0; made_move= '0'; // If current state is ai_try_win, we're looking for rows

Page 62: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

55 ai_find_win: Try to Win Or Block

// containing "O" marks that can be completed to win // If current state is ai_try_block, we're looking for rows // containing "X" marks that can be blocked to prevent opponent from winning if(curr_state == ai_try_win){ mark= "11"; }else { mark= "01"; } // Step 1 - Try to find a winning move // i.e. find a row containing two circles an one empty space L2: for(i = 0; i < 3; i++){ // find a nearly complete horizontal row if(ga_array_in(i,0) == "00" AND ga_array_in(i,1) == mark AND ga_array_in(i,2) == mark){ row_id_temp= i; col_id_temp= 0; made_move= '1'; } else if( ga_array_in(i,0) == mark AND ga_array_in(i,1) == "00" AND ga_array_in(i,2) == mark){ row_id_temp= i; col_id_temp= 1; made_move= '1'; } else if( ga_array_in(i,0) == mark AND ga_array_in(i,1) == mark AND ga_array_in(i,2) == "00"){ row_id_temp= i; col_id_temp= 2; made_move= '1'; // find a nearly complete vertical row } else if( ga_array_in(0,i) == "00" AND ga_array_in(1,i) == mark AND ga_array_in(2,i) == mark){ row_id_temp= 0; col_id_temp= i; made_move= '1'; } else if( ga_array_in(0,i) == mark AND ga_array_in(1,i) == "00" AND ga_array_in(2,i) == mark){ row_id_temp= 1; col_id_temp= i; made_move= '1'; } else if( ga_array_in(0,i) == mark AND ga_array_in(1,i) == mark AND ga_array_in(2,i) == "00"){ row_id_temp= 2; col_id_temp= i; made_move= '1'; } } if made_move == '0'{ // find a nearly complete diagonal row if(ga_array_in(0,0) == "00" AND ga_array_in(1,1) == mark AND ga_array_in(2,2) == mark){ row_id_temp= 0; col_id_temp= 0; made_move= '1';

Page 63: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

56 ai_fork: Try to Make a Fork

} else if( ga_array_in(0,0) == mark AND ga_array_in(1,1) == "00" AND ga_array_in(2,2) == mark){ row_id_temp= 1; col_id_temp= 1; made_move= '1'; } else if( ga_array_in(0,0) == mark AND ga_array_in(1,1) == mark AND ga_array_in(2,2) == "00"){ row_id_temp= 2; col_id_temp= 2; made_move= '1'; } else if( ga_array_in(0,2) == "00" AND ga_array_in(1,1) == mark AND ga_array_in(2,0) == mark){ row_id_temp= 0; col_id_temp= 2; made_move= '1'; } else if( ga_array_in(0,2) == mark AND ga_array_in(1,1) == "00" AND ga_array_in(2,0) == mark){ row_id_temp= 1; col_id_temp= 1; made_move= '1'; } else if(ga_array_in(0,2) == mark AND ga_array_in(1,1) == mark AND ga_array_in(2,0) == "00"){ row_id_temp= 2; col_id_temp= 0; made_move= '1'; } } // If a nearly complete row is found, AI adds an "O' mark to the empty cell of the row if(made_move == '1'){ ai_mademove = '1'; }else { // Otherwise, AI does not make a move ai_mademove = '0'; } // Pass on the row and column values as output to confirm the move row_id = row_id_temp; col_id = col_id_temp; }else { ai_mademove = '0'; row_id = 0; col_id = 0; }

AI_FORK: TRY TO MAKE A FORK

DESCRIPTION

The “ai_fork” component is active when the current state of the finite state machine is

“ai_try_fork”. This component allows the AI to determine whether it can win in its next turn. To

Page 64: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

57 ai_fork: Try to Make a Fork

do so, it must create a fork, i.e. a situation where there exists two empty cells in the game table

such that adding an “O” mark on either space results in an AI win. In code, we use a trial-and-

error method: assume that the AI adds an “O” mark in the first empty space it encounters. If it

is able to create a fork, the component updates its outputs by setting the “row_id” and “col_id”

signals to select the space that was initially chosen.

If no fork is found, the AI restarts, adding an “O” mark in the next empty cell it finds in the

game table and the process above is executed again until a potential fork is found or until all

empty spaces have been checked.

As with all other components dealing with the AI’s playing strategy, the “ai_mademove” signal

is used to notify the controller that the AI has made a move during the “ai_fork” state.

DESCRIPTION OF THE I/O PINS

The “ai_fork” component has exactly the same pin configuration as the “ai_try_win”

component (as do all the components handling the AI strategy).

Input Pins:

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

ga_array_in: std_table

o Outputted by the “ga_array” component

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

Output Pins:

row_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

Page 65: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

58 ai_fork: Try to Make a Fork

o The row index of the newly inserted “X” mark

col_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The column index of the newly inserted “X” mark

ai_mademove: std_logic

o Outputted towards the game table component “ga_array”

o Indicates that the AI has successfully made a move

FIGURE 42: BLOCK DIAGRAM OF THE AI_FORK COMPONENT

SIMULATIONS AND WAVEFORMS

To test the “ai_fork” component, we simulate different board combinations and see if the AI is

able to find a fork. Since our code heavily borrows from the “ai_find_win” component, we do

not need to test all possible fork combinations. Hence, we shall only test the behaviour of the

component in the following conditions:

A fork can be created due to two winning moves being found after adding the “O” mark

No fork can be created due to only one winning move being found after adding the “O”

mark

No fork can be created and no winning moves are found

FIGURE 43: WAVEFORM FOR AI_FORK

In the above waveform, we apply the forking algorithm in different situations:

Page 66: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

59 ai_fork: Try to Make a Fork

In the first clock cycle, the AI successfully adds an “O” mark in the bottom-right corner,

creating a fork from the bottom horizontal and right-most diagonal rows. It acknowledges the

move by setting the “ai_mademove” signal high. We tried another fork possibility in the third

clock cycle.

In the second clock cycle, the whole game table is full; hence, no winning move can be made by

adding an “O” mark since no new “O” mark can be added. Therefore, no move is made from

the “ai_fork” component (“ai_mademove” = ‘0’).

In the fourth test, we look at the case where the AI can find one winning move after adding an

“O” mark in an empty space (in this case, cells (1,1) and (1,2)). Since a fork is created when at

least two winning moves are found, the AI recognises this and drops this possibility. But there

are no forks that can be created in this circumstance, so “ai_mademove” is set at ‘0’.

Finally, the case of an empty table is investigated. There are obviously no forks that can be

made since a minimum of three “O” marks need to be on the field for a fork to exist.

Fortunately, the AI catches this and does not decide to make a move with this component.

PSEUDOCODE

if(curr_state == ai_try_fork){ // Sweep through all possible next moves (i.e. any empty cell) // until a fork is found L1: for(i = 0; i < 3; i++){ L2: for(j = 0; j < 3; j++){ if(ga_array_in(i,j) == "00"){ made_move= 0; ga_array_temp= ga_array_in; ga_array_temp(i,j)= "11"; // Count the number of nearly complete rows that can be completed in the next turn L3: for(k = 0; k < 3; k++){ // find a nearly complete horizontal row if(ga_array_temp(k,0) == "00" AND ga_array_temp(k,1) == "11" AND ga_array_temp(k,2) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(k,0) == "11" AND ga_array_temp(k,1) == "00" AND ga_array_temp(k,2) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(k,0) == "11" AND ga_array_temp(k,1) == "11" AND ga_array_temp(k,2) == "00"){

Page 67: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

60 ai_fork: Try to Make a Fork

made_move= made_move + 1; } // find a nearly complete vertical row if(ga_array_temp(0,k) == "00" AND ga_array_temp(1,k) == "11" AND ga_array_temp(2,k) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(0,k) == "11" AND ga_array_temp(1,k) == "00" AND ga_array_temp(2,k) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(0,k) == "11" AND ga_array_temp(1,k) == "11" AND ga_array_temp(2,k) == "00"){ made_move= made_move + 1; } } // find a nearly complete diagonal row if(ga_array_temp(0,0) == "00" AND ga_array_temp(1,1) == "11" AND ga_array_temp(2,2) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(0,0) == "11" AND ga_array_temp(1,1) == "00" AND ga_array_temp(2,2) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(0,0) == "11" AND ga_array_temp(1,1) == "11" AND ga_array_temp(2,2) == "00"){ made_move= made_move + 1; } if(ga_array_temp(0,2) == "00" AND ga_array_temp(1,1) == "11" AND ga_array_temp(2,0) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(0,2) == "11" AND ga_array_temp(1,1) == "00" AND ga_array_temp(2,0) == "11"){ made_move= made_move + 1; } else if(ga_array_temp(0,2) == "11" AND ga_array_temp(1,1) == "11" AND ga_array_temp(2,0) == "00"){ made_move= made_move + 1; } // If 2 or more winning rows can be made, AI can create a fork // Confirm the row & column coordinates of the inserted O mark creating the fork if(made_move > 1){ row_id = i; col_id = j; ai_mademove ='1'; exit L1; // If no fork is found after cycling through all possible next moves, do not make a move }else { row_id = 0; col_id = 0; ai_mademove = '0'; } }else {

Page 68: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

61 ai_block_fork: Try to Block a Fork

row_id = 0; col_id = 0; ai_mademove = '0'; } } } }else { row_id = 0; col_id = 0; ai_mademove = '0'; }

AI_BLOCK_FORK: TRY TO BLOCK A FORK

DESCRIPTION

The block fork circuit’s job is to determine possible forks that the human player (HP) can use on

their next move and to prevent these forks. It’s placed 4th circuit in hierarchy in the FSM for the

AI move decision making task.

The circuit is activated if the “curr_state” signal is equal to ‘ai_try_blockfork’. It does not follow

the clock of the circuit directly since it is designed to follow only any change of state. If the

circuit detects a possible fork, the circuit outputs the coordinates of the cell where the AI

should insert an “O” mark to prevent the possible fork and also setting the signal

“ai_mademove” high to signal that the AI made a move. If the circuit does not detect any

possible fork, then it outputs the signal “ai_mademove” as low indicating that the circuit failed

and the FSM should jump to the next state.

The algorithm used to detect forks is as follow: The circuit will scan the input tic-tac-toc table

“STD_TABLE” row by row, column by column, and the two diagonals. The circuit searches for

instances of rows where only one ‘X’ mark are within (with two empty cells) and marks these

rows as possible parts for a fork. When all rows are checked, the circuit scans the table cell by

cell for instances of cells which happen to be the intersection points of two or more rows which

have been marked as possible parts of a fork. If a cell happens to have such characteristic, then

a mark ‘X’ at such location would create a fork to the HP advantage.

Page 69: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

62 ai_block_fork: Try to Block a Fork

To prevent the possible fork, the circuit will insert an “O” mark at the fork cell for normal cases.

However there are special cases of forks which will not be prevented by simply filling the cell

where the fork can happen. These cases and how they are prevented are presented in the

images below.

DESCRIPTION OF THE I/O PINS

The “ai_fork” component has exactly the same pin configuration as the “ai_try_win”

component (as do all the components handling the AI strategy).

Input Pins:

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

ga_array_in: std_table

o Outputted by the “ga_array” component

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

Output Pins:

row_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

Page 70: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

63 ai_block_fork: Try to Block a Fork

o The row index of the newly inserted “X” or “O” mark

col_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The column index of the newly inserted “X” or “O” mark

ai_mademove: std_logic

o Outputted towards the game table component “ga_array”

o Indicates that the AI has successfully made a move

FIGURE 44: BLOCK DIAGRAM OF THE AI_BLOCK_FORK COMPONENT

SIMULATIONS AND WAVEFORMS

In the first waveform (fork1), a few sample cases of forks are shown to be detected and the

output coordinates “row_id” and “col_id” correspond to the cell where the ‘O’ mark needs to

be inserted to prevent the fork. Note that in certain of the test cases the AI could have directly

picked a different coordinate to immediately win the game, but for the sake of this circuit, we

will only consider the fork blocking process.

FIGURE 45: FIRST SIMULATION WAVEFORM FOR THE AI_BLOCK_FORK COMPONENT

The second waveform (fork2) shows when the circuit fails to detect any fork and thus the

“ai_mademove” signal is low and the outputs coordinates will be ignored. The first clock cycle

was used to show that the circuit is still performing its assigned task. In the following clock

cycles, the cases tested are:

Page 71: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

64 ai_block_fork: Try to Block a Fork

1. Only 1 ‘O’ and 1 ‘X’ on GA

2. Only 1 ‘X’ on GA

3. A full GA

4. An empty GA

5. A few random cases.

All cases demonstrated that the circuit failed to find a possible fork for the HP, which is correct

for these test cases.

FIGURE 46: SECOND SIMULATION WAVEFORM FOR THE AI_BLOCK_FORK COMPONENT

The third waveform (fork3) tests the cases for the special forks mentioned in the figures

previously presented. As expected, the AI was not duped by placing the ‘O’ mark directly on

top of the fork cell, but responded by an acceptable placement of the ‘O’ mark which force the

HP to respond to the threat of a two ‘O’ marks row.

FIGURE 47: THIRD SIMULATION WAVEFORM FOR THE AI_BLOCK_FORK COMPONENT

PSEUDOCODE

if (curr_state == ai_try_blockfork ) { // Since we are blocking, we try to find 'X' marks, but if needed, this code can be used // by the AI to find potential forks with mark 'O'. It can be done like so: // if(curr_state == ai_try_fork) // mark == "11"; // else if(curr_state == ai_try_blocking) // mark == "10"; // }

Page 72: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

65 ai_block_fork: Try to Block a Fork

mark = "10"; r0= FALSE; r1= FALSE; r2= FALSE; c0= FALSE; c1= FALSE; c2= FALSE; d0= FALSE; d1 = FALSE; GA_t = GA; count_t_l_r = 0; count_t_r_l = 0; // Checking for rows where there is only one target mark (while the 2 other cells are empty) // The algorithm uses addition of integers to determine the amount of empty and mark elements // in each row. for(int i=0; i<3; i++){ count_t_row = 0; count_t_col = 0; for(int j=0; j<3; j++){ // checking the horizontal rows if(GA(i,j) == "00"){ count_t_row = count_t_row + 3; }else if(GA(i,j) == mark){ count_t_row = count_t_row + 1; } // checking the columns if(GA(j,i) == "00"){ count_t_col = count_t_col + 3; }else if{(GA(j,i) == mark) count_t_col = count_t_col + 1; } // only check the diagonals once. if(i == 0){ // checking the left to right diagonal (left bottom corner to upper right corner) if(GA_t(j,j) == "00"){ count_t_l_r = count_t_l_r + 3; } else if(GA_t(j,j) == mark){ count_t_l_r = count_t_l_r + 1; } //checking the right to left diagonal if(GA_t(2-j,j) == "00"){ count_t_r_l = count_t_r_l + 3; }else if(GA_t(2-j,j) == mark){ count_t_r_l = count_t_r_l + 1;

Page 73: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

66 ai_block_fork: Try to Block a Fork

} } } // If the sum of the integers represent a row with only one mark and two empty cells, // that row is a potential candidate for a fork. if(i == 0){ if(count_t_row == 7){ r0 = true; } if(count_t_col == 7){ c0 = true; } } if(i == 1){ if(count_t_row == 7){ r1 = true; } if(count_t_col == 7){ c1 = true; } } if(i == 2){ if(count_t_row == 7){ r2 = true; } if(count_t_col == 7){ c2 = true; } } end case; } // The row evaluation for the diagonals can be done only once. if(count_t_l_r == 7){ d0 = true; } if(count_t_r_l == 7){ d1 = true; } ai_mademove = '1'; // here we assume that no row contains 2 of the same mark since this case is covered // by a component of higher hierarchy. // tricky forks from HP // When one 'O' mark in a corner and two 'X' marks on the same diagonal as the 'O' mark. if(r1 AND c1 AND((r2 AND c2)OR(r0 AND c0)) AND mark == "10" AND GA_t(0,2) == "00"){ row_id = 0; col_id = 2;

Page 74: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

67 ai_direct_write: Other Strategies

}else if(r1 AND c1 AND((r2 AND c0)OR(r0 AND c2)) AND mark == "10" AND GA_t(0,2) == "00"){ row_id = 0; col_id = 0; // When one 'O' mark in the middle and two 'X' marks on opposite corners }else if(r0 AND c0 AND r2 AND c2 AND mark == "10" AND GA_t(0,1) == "00"){ row_id = 0; col_id = 1; // normal forks below }else if(((r0 AND c0) OR ((r0 OR c0)AND(d0))) AND GA_t(0,0) == "00"){ row_id = 0; col_id = 0; }else if(r0 AND c1 AND GA_t(0,1) == "00"){ row_id = 0; col_id = 1; }else if(((r0 AND c2) OR ((r0 OR c2)AND(d1))) AND GA_t(0,2) == "00"){ row_id = 0; col_id = 2; }else if(r1 AND c0 AND GA_t(1,0) == "00"){ row_id = 1; col_id = 0; }else if(((r1 AND c1) OR ((r1 OR c1)AND(d0 OR d1)) OR (d0 AND d1)) AND GA_t(1,1) == "00"){ row_id = 1; col_id = 1; }else if(d0 AND d1 AND GA_t(1,1) == "00"){ row_id = 1; col_id = 1; }else if(r1 AND c2 AND GA_t(1,2) == "00"){ row_id = 1; col_id = 2; }else if(((r2 AND c0) OR ((r2 OR c0)AND(d1))) AND GA_t(2,0) == "00"){ row_id = 2; col_id = 0; }else if(r2 AND c1 AND GA_t(2,1) == "00"){ row_id = 2; col_id = 1; }else if(((r2 AND c2) OR ((r2 OR c2)AND(d0))) AND GA_t(2,2) == "00"){ row_id = 2; col_id = 2; // when all possibilities fail, move incomplete. }else{ ai_mademove = '0'; } }else{ ai_mademove = '0'; }

AI_DIRECT_WRITE: OTHER STRATEGIES

Page 75: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

68 ai_direct_write: Other Strategies

DESCRIPTION

The “ai_direct_write” component is the final element of the AI’s strategy on all but the lowest

difficulty level. It is active only during the “ai_try_direct” state.

The strategy behind this component follows this order:

If the centre cell has not been taken already, take it.

Otherwise, check if the opponent has played in a corner opposing an empty corner. If

so, play on that empty corner.

Otherwise, take any available (i.e. empty) corner

If all corners are taken, take any available side cell (any non-centre and non-corner cell)

As with all other components dealing with the AI’s playing strategy, the “ai_mademove” signal

is used to notify the controller that the AI has made a move during the “ai_try_direct” state,

stopping the AI strategy (although it’s impossible for this not to happen unless the game table

is filled, in which case the “status” state will signal the tie before giving a chance for the AI

strategy to start again.

DESCRIPTION OF THE I/O PINS

The “ai_direct_write” component has exactly the same pin configuration as the “ai_try_win”

component (as do all the components handling the AI strategy).

Input Pins:

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

ga_array_in: std_table

o Outputted by the “ga_array” component

Page 76: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

69 ai_direct_write: Other Strategies

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

Output Pins:

row_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The row index of the newly inserted “X” mark

col_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The column index of the newly inserted “X” mark

ai_mademove: std_logic

o Outputted towards the game table component “ga_array”

o Indicates that the AI has successfully made a move

FIGURE 48: BLOCK DIAGRAM OF THE AI_DIRECT_WRITE COMPONENT

SIMULATIONS AND WAVEFORMS

The “ai_direct_write” component is very easy to test since the logic represents a series of

cascading if statements.

First, we test if the first part of the strategy, that is, taking the centre, is working. In the first

waveform, we tested this case in the first clock cycle. As expected, the circuit works as the AI

signals its move by setting the “ai_mademove” output to ‘1’ with the centre cell coordinates

(“row_id” = 1, “col_id” = 1) as output.

In the next clock cycles, the centre is non-empty, allowing for the rest of the strategy to run.

Here, we place an “X” mark in one corner of the game table. Consequently, the AI places an

Page 77: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

70 ai_direct_write: Other Strategies

“O” mark in the corner cell opposite the corner where the human player has placed an “X”

mark.

FIGURE 49: WAVEFORM OF AI_DIRECT_WRITE FOR THE FIRST TWO SUBSTRATEGIES

Next, we block opposing corners and observe that the AI proceeds with the next part of its

strategy: playing in any available corner. We observe that this is the case in the first part of the

second waveform.

Finally, we test the final part of the strategy by forcing the AI to play on a side cell. Once again,

we see that the component is functioning as it should.

FIGURE 50: WAVEFORM OF AI_DIRECT_WRITE FOR THE LAST TWO SUBSTRATEGIES

PSEUDOCODE

if(curr_state == ai_try_direct){ // Step 1 - Take the Centre if available if(ga_array_in(1,1) == "00"){ row_id_temp= 1; col_id_temp= 1; // Step 2 - If the opponent has taken a corner // take the opposite corner if it's available } else if(ga_array_in(0,0) == "01" AND ga_array_in(2,2) == "00"){ row_id_temp= 2; col_id_temp= 2; } else if(ga_array_in(0,2) == "01" AND ga_array_in(2,0) == "00"){ row_id_temp= 2; col_id_temp= 0; } else if(ga_array_in(2,0) == "01" AND ga_array_in(0,2) == "00"){ row_id_temp= 0; col_id_temp= 2; } else if(ga_array_in(2,2) == "01" AND ga_array_in(0,0) == "00"){

Page 78: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

71 ai_random: Very Dumb AI

row_id_temp= 0; col_id_temp= 0; // Step 3 - Take the first corner that is empty } else if(ga_array_in(0,0) == "00"){ row_id_temp= 0; col_id_temp= 0; } else if(ga_array_in(0,2) == "00"){ row_id_temp= 0; col_id_temp= 2; } else if(ga_array_in(2,0) == "00"){ row_id_temp= 2; col_id_temp= 0; } else if(ga_array_in(2,2) == "00"){ row_id_temp= 2; col_id_temp= 2; // Step 4 - Take the first empty side } else if(ga_array_in(0,1) == "00"){ row_id_temp= 0; col_id_temp= 1; } else if(ga_array_in(1,2) == "00"){ row_id_temp= 1; col_id_temp= 2; } else if(ga_array_in(1,0) == "00"){ row_id_temp= 1; col_id_temp= 0; } else if(ga_array_in(2,1) == "00"){ row_id_temp= 2; col_id_temp= 1; } else{ row_id_temp= 0; col_id_temp= 0; } // Add a circle by specifying the proper row & column ids and setting ai_mademove to 1 row_id = row_id_temp; col_id = col_id_temp; ai_mademove = '1'; } else{ // If not in the ai_try_direct, avoid making a move ai_mademove = '0'; row_id = 0; col_id = 0; }

AI_RANDOM: VERY DUMB AI

DESCRIPTION

Page 79: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

72 ai_random: Very Dumb AI

The random circuit’s job is simply filling out the first available free cell with an ’O’ mark when

no other strategies or counter strategies can be applied. The circuit will search for such a cell

from left to right and bottom to top.

The circuit is activated if the “curr_state” signal is equal to ‘ai_random’. It does not follow the

clock of the circuit directly since it is designed to follow only any change of state. When all

other strategies are unavailable, the circuit will simply fill out the first available cell in the order

presented on the image below.

FIGURE 51: SCANNING ORDER OF THE AI_RANDOM COMPONENT

DESCRIPTION OF THE I/O PINS

The “ai_fork” component has exactly the same pin configuration as the “ai_try_win”

component (as do all the components handling the AI strategy).

Input Pins:

curr_state: state_type

o A one-hot encoded value representing the current state of the finite state

machine.

o Synchronised to the clock via the controller. Hence, acts as a clock.

o At most, the function will only execute once during a clock cycle: at the change

in state

ga_array_in: std_table

o Outputted by the “ga_array” component

o Representation of the current state of the game table

o Used to locate all the “X” and “O” marks

Output Pins:

Page 80: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

73 ai_random: Very Dumb AI

row_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The row index of the newly inserted “O” mark

col_id: integer range 0 to 2

o Outputted towards the game table component “ga_array”

o The column index of the newly inserted “O” mark

ai_mademove: std_logic

o Outputted towards the game table component “ga_array”

o Indicates that the AI has successfully made a move

FIGURE 52: BLOCK DIAGRAM OF THE AI_RANDOM COMPONENT

SIMULATIONS AND WAVEFORMS

The waveform presented below simply demonstrates what was explained previously. The

outputted “row_id” and “col_id” coordinates indicate correctly the first cell available in each

presented cases. In the last case, when the GA is filled, the circuit fails (“ai_mademove” = 0)

and no ‘O’ mark will be inserted. For the sake of showcasing this circuit, please ignore the fact

that certain test cases contain full rows of ‘X’ marks.

FIGURE 53: SIMULATION WAVEFORM FOR THE AI_RANDOM COMPONENT

PSEUDOCODE

Page 81: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

74 ai_random: Very Dumb AI

if(curr_state = ai_random){ ai_mademove = '1'; if(ga_array_in(0,0)="00"){ row_id = 0; col_id = 0; } else if(ga_array_in(0,1)="00"){ row_id = 0; col_id = 1; } else if(ga_array_in(0,2)="00"){ row_id = 0; col_id = 2; } else if(ga_array_in(1,0)="00"){ row_id = 1; col_id = 0; } else if(ga_array_in(1,1)="00"){ row_id = 1; col_id = 1; } else if(ga_array_in(1,2)="00"){ row_id = 1; col_id = 2; } else if(ga_array_in(2,0)="00"){ row_id = 2; col_id = 0; } else if(ga_array_in(2,1)="00"){ row_id = 2; col_id = 1; } else if(ga_array_in(2,2)="00"){ row_id = 2; col_id = 2; }else{ ai_mademove = '0'; row_id = 0; col_id = 0; } }else{ ai_mademove = '0'; row_id =0; col_id =0; }

PROPOSED MODIFICATIONS TO DESIGN

Upon the verified completion of the overall design given the requirements of the lab, we had

some extra time to implement some special extra features (difficulty levels, AI able to strt the

game, a pointer on the hex display showing the current location selected by the user). Due to

the relative robustness of the design, such modifications were very easy to implement.

However, we can still think of additional modifications we could have added to our design as

follows:

Page 82: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

75 ai_random: Very Dumb AI

Our code is relatively coded at a high-level. Therefore, there is some performance loss at the

expense of greater clarity in our code. This loss isn’t too great since we are barely using any of

the resources available to the Altera board. Still, it is possible to optimize the performance of

the design and should be considered if it needs to be implemented on a smaller chip.

The bulkiest component in our design is without a doubt the bus multiplexer “ga_array_mux”.

It’s possible to completely eliminate this . Since all our AI strategy components have the same

inputs and outputs and active at different times (different state), we could have considered

merging all of these entities together, eliminating the need of a multiplexer like the

“ga_array_mux” component. Timing might be an issue though.

The AI, while it can never lose and tries to win quite effectively, is not perfect. To be perfect,

the AI must make its move such that it has the greatest chance of winning. However, doing this

would involve hardcoding all of the AI’s moves, which may improve playing performance but

would affect our general understanding of the design.

PROBLEMS ENCOUNTERED

Outside of inevitable syntax errors and other problems that were easily taken care of, we had

encountered more challenging errors during the integration stage of our overall design.

We initially had a single common signal acting as inputs to the ga_array instead of a

multiplexor. Even though we thought that the signal worked, due to the crcuit working for the

AI’s first move, the AI sometimes failed to place an “O” in the correct place. In the end, we

were forced to use a mux component “ga_array_mux” to control the signals that we want to

connect to the “ga_array”.

First of all, our initial designs for each component were such that the process blocks described

in those components were all executed at the edge of the clock. The result of this design was

that, at the rising edge of the clock, all inputs were the values calculated in the previous state.

This was the notably the case for the input game array “ga_arrray_in” of each component. This

problem was fixed once we made all components run only upon a change in state rather than

the edge of the clock.

Page 83: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

76 ai_random: Very Dumb AI

However, this solution led to the creation of unwanted inferred latches, which we removed in

the code once we found them. This fixed the problem for good.

CONCLUSION

In the end, it was an interesting experience designing logical circuits on hardware. We learned

much about the quirks of hardware description languages and how they compare to

“traditional” computer programming. Although we struggled through the project integration

stage, we gained a lot of knowledge about the process. In future projects, we would like to see

some more low-level design rather than the simple project that was Tic-Tac-Toe.

Page 84: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

77 Appendix I: Global Architecture of the Game (ttt.vhd)

APPENDIX

APPENDIX I: GLOBAL ARCHITECTURE OF THE GAME (TTT.VHD)

FIGURE 54: BLOCK DIAGRAM OF THE GAME

Page 85: ECSE 323 - Tic Tac Toe Game on FPGA Board - Report

78 Appendix II: Finite State Machine

APPENDIX II: FINITE STATE MACHINE

( S E E C O N T R O L L E R S E C T I O N T O V I E W I N D E T A I L )

FIGURE 55: FINITE STATE MACHINE DIAGRAM FOR THE COMPLETE GAME

sg

hp

_m

ove

sta

tus

los

stie

win

ai_

try_w

ina

i_try_

blo

ck

ai_

ran

do

ma

i_try_

fork

ai_

try_b

lockfo

rka

i_try_

dire

ct

reset

ai_

sta

tus