You are on page 1of 14

VHDL SIMULATIONS

https://drive.google.com/drive/folders/11z1hCb1Qm0tfx5xHclhRMFfWBMeHWJaJ?usp=sharin
g

REGISTER BANK

By resetting, the bank_ready is set to 1 in order to indicate that a new code can be stored
inside. Also, key_read is set to 0 as we have not read any key yet and the value that we need to
read we put it at 0 also, the three different buffers representing the units, tenths and
hundreds.

Once the reset is done and we have a rising edge of the clock we enter to the wait state. It
waits for the main block to send a code for the user or for the game block for registering the
guessing code. We pass this wait state only when we receive a signal called new_code, and this
signal must be set to 1. This reception of the new_code signal activates the register block.

After that, we set the bank_ready to 0 because the register_bank is now occupied storing a
new value. We enter the w_keypress state, where it waits for the user to press any key. At this
moment, we are listening to the keyboard. If the user presses any bcd value, we activate just
the key_read signal order to acknowledge that the key has been read. In addition, the bcd flag
is up when we are pressing the bcd values.

We can also observe how it stores first the number code into the data units, the old data units
pass to the data tenths, and the old data tenths go to the data hundreds, this is how the values
get updated. This behavior can be seen if we check the evolution of the key_code variable,
DataH, DataT and DataU.

After the 3 bcd signals are pressed, the user presses ‘*’ and the ast signal is activated until the
key is read. Then, it deactivates the ast flag and acknoledge that the key has been read.
Bank_ready is sent again to 1, in order to let know that the code is available.

As we can see, each of the outputs that take part in the Control Unit are defined out of the
process so as to avoid undesire issues and results when simulating. We have applied this in all
codes.
library ieee;
use ieee.std_logic_1164.all;

entity register_bank is
port (
clk50, nrst: in std_logic;
bcd, ast, new_code: in std_logic;
key_code: in std_logic_vector(3 downto 0);
DataH, DataT, DataU : out std_logic_vector(3 downto 0);
key_read, bank_ready : out std_logic
);
end register_bank;

architecture main of register_bank is


type state_type is (r_wait, w_keypress, get_key, r_end );
signal state : state_type;
signal data_t, data_u, data_h : std_logic_vector(3 downto 0);

begin
PROTOCOL_FSM: process (clk50, nrst)
begin
if nrst = '0' then
state <= r_wait;
bank_ready <= '1';
data_h <= "0000";
data_t <= "0000";
data_u <= "0000";

elsif clk50'EVENT and clk50 = '1' then


case state is
when r_wait =>
if new_code = '1' then
bank_ready <= '0';
data_h <= "0000";
data_t <= "0000";
data_u <= "0000";
state <= w_keypress;
end if;

when w_keypress =>


if bcd = '1' then
state <= get_key;
elsif ast = '1' then
state <= r_end;
bank_ready <='1';
end if;

when get_key =>


data_h <= data_t;
data_t <= data_u;
data_u <= key_code;
state <= w_keypress;

when r_end =>


state <= r_wait;
end case;
end if;
end process;

DataH <= data_h;


DataT <= data_t;
DataU <= data_u;

-- Outputs of the control unit. Always out of the process.

key_read <= '1' when (state = get_key or state = r_end) else '0';

end;
GAME

When we reset, the lights are off and the outputs go to 0 as an initialization procedure. The
game block will stay at this point until it receives an input activated by the main block called
new_game, meaning that the user has already registered its code in the register bank. To start
the game, the system sends the ready frame after checking if the transmitter block is ready to
transmit. When it is ready to transmit, the game block activates the output SEND_RDY in order
to send the ready frame. It will wait in this state until the receiver has activated the
RDY_RECEIVED flag.

Then, the FRAME_READ output is activated in order to deactivate the previous flag and also
the enterCode output is activated which enables the register bank to store the guessing code.
Afterwards, the user can enter its own code and it notices that because the LightD is turned on
in order to alert him.

The next step is to enter the code and when it has finished entering the code it will press the
asterisc key which will make the register block to activate the bank_ready output, that will be
an input to the game block.

When we have this input active, it means that we have entered the code and then the LightD is
turned off again.

In the next phase, we need to send and receive the data frame. After checking if the
transmitter is ready to transmit we activate the output SEND_DT and we wait until the receiver
has activated the flag DT_RECEIVED, meaning that it has received our data frame and the
guessing code of the opponent. To deactivate this flag, we activate the FRAME_READ.

Now, we must send the result of the comparison between the two codes. There are three
posible outcomes of this comparison. That the code is greater than the one suggested, that it is
smaller or that is exactly equal.

If it is greater or smaller the game continues, then we will send the output SEND_GR or
SEND_SM depending on the result of the comparison. Also, we have to wait to the result of the
comparison of our guessing code and the opponent code. It will also have three outcomes.

The user is warned by the lights if the code has been guessed correctly, or if it is higher or
lower. The output FRAME_READ is activated in order to deactivate the respective SM, EQ or
GR flags and if it has not guessed it correctly the game starts another iteration.

When the Game block received the frame EQ_RECEIVED, lights on the lightW in order to let
the user know that has one and it goes to the initial state to start a new game.

If the opponent has guessed our code, we need to send a SEND_EQ signal. This has two
outcomes, lose the game or tie it. If we have lost the game, we activate the corresponding light
and we activate the FRAME_READ in order to deactivate the other flags. If the match is tied,
we activate the light that corresponds and we also activate the FRAME_READ to deactivate the
EQ_RECEIVED flag and the SEND_EQ flag from the receiver block. Finally, we start a new game
by going to the first state.
Simulation: In order to develop the vector waveform simulation, we have stated 4 inputs:
keycode, hash, ast and bcd. We have to imagine if the user is in front of the board ready to
start the game. The same way, in order to validate the correct functionality, we add the node
"state" to validate each of the states along the simulation. Despite, we think we have a little
problem when simulating because of the nrst. We would like to comment this final simulation
with you whenever is possible.

library ieee;
use ieee.std_logic_1164.all;

entity Game is
port (
clk50, nrst: in std_logic;
RDY_RECEIVED, GR_RECEIVED, EQ_RECEIVED, SM_RECEIVED,
DT_RECEIVED, new_game: in std_logic;
Our_H, Our_T, Our_U: in std_logic_vector(3 downto 0);
Opponent_H,Opponent_T, Opponent_U : in std_logic_vector(3 downto 0);
ready_to_TX, bank_ready : in std_logic;

SEND_RDY, SEND_GR, SEND_EQ, SEND_SM, SEND_DT: out std_logic;


frame_received: out std_logic;
LightD, LightG, LightS, LightWIN, Light_Loose, Light_Tie: out std_logic;
enterCode: out std_logic
);
end Game;

architecture main of Game is


type state_type is (g_wait, w_tx1, S_RDY, W_RDY, Code, W_Code, W_Tx2, S_DT,
W_DT, FR_R, W_Tx3, S_GRorSM, W_FR, S_EQ, W_FR2);
signal state : state_type;
signal GR,SM,EQ: std_logic;

begin
PROTOCOL_FSM: process (clk50, nrst)
begin

if nrst = '0' then


state <= g_wait;
LightD <= '0';
LightG <= '0';
LightS <= '0';
LightWIN <= '0';
Light_Loose <= '0';
Light_Tie <= '0';

elsif clk50'EVENT and clk50 = '1' then


case state is

when g_wait =>


if New_Game = '1' then
state <= w_tx1;
end if;

when w_tx1 =>


if ready_to_TX = '1' then
state <= S_RDY;
end if;

when S_RDY =>


state <= W_RDY;

when W_RDY =>


if RDY_RECEIVED = '1' then
state <= Code;
end if;
when Code =>
LightD <= '1';
state <= W_Code;

when W_Code =>


if bank_ready = '1' then
LightD <= '0';
state <= W_Tx2;
end if;

when W_Tx2 =>


if ready_to_TX = '1' then
state <= S_DT;
end if;

when S_DT =>


state <= W_DT;

when W_DT =>


if DT_RECEIVED = '1' then
state <= FR_R;
end if;

when FR_R =>


state <= W_Tx3;

when W_Tx3 =>


if (ready_to_TX = '1' and EQ = '1') then
state <= S_EQ;
elsif (ready_to_TX = '1' and (GR = '1' or SM = '1')) then
state <= S_GRorSM;
end if;
when S_EQ =>
state <= W_FR2;

when S_GRorSM =>


if (GR = '1') then
state <= W_FR;
elsif(SM = '1') then
state <= W_FR;
end if;

when W_FR2 =>


if (EQ_RECEIVED = '1') then
Light_Tie <= '1';
LightD <= '0';
LightG <= '0';
LightS <= '0';
Light_Loose <= '0';
LightWIN <= '0';
state <= g_wait;
elsif(SM_RECEIVED = '1' or GR_RECEIVED = '1') then
Light_Loose <= '1';
LightD <= '0';
LightG <= '0';
LightS <= '0';
Light_Tie <= '0';
LightWIN <= '0';
state <= g_wait;
end if;

when W_FR =>


if (EQ_RECEIVED = '1') then
LightWIN <= '1';
LightD <= '0';
LightG <= '0';
LightS <= '0';
Light_Loose <= '0';
Light_Tie <= '0';
state <= g_wait;
elsif(SM_RECEIVED = '1') then
LightS <= '1';
LightWIN <= '0';
LightD <= '0';
LightG <= '0';
Light_Loose <= '0';
Light_Tie <= '0';
state <= g_wait;
elsif(GR_RECEIVED = '1') then
LightG <= '1';
LightWIN <= '0';
LightD <= '0';
LightS <= '0';
Light_Loose <= '0';
Light_Tie <= '0';
state <= g_wait;
end if;
end case;
end if;
end process;

-- Outputs of the control unit. Always out of the process.

enterCode <= '1' when state = W_Code else '0';


SEND_DT <= '1' when state = S_DT else '0';
SEND_EQ <= '1' when state = S_EQ else '0';
SEND_SM <= '1' when (state = S_GRorSM and SM = '1') else '0';
SEND_GR <= '1' when (state = S_GRorSM and GR = '1') else '0';
SEND_RDY <= '1' when state = S_RDY else '0';
frame_received <= '1' when state = Code or
state = FR_R or
(state = W_FR2 and EQ_RECEIVED = '1') or
(state = W_FR2 and (SM_RECEIVED = '1' or GR_RECEIVED = '1')) or
(state = W_FR and EQ_RECEIVED = '1') or
(state = W_FR and GR_RECEIVED = '1') or
(state = W_FR and SM_RECEIVED = '1') else '0';

end;
MAIN BLOCK

When we reset, we set the GAME_OVER signal to 1 and we set key_read, new_code,
new_game and LED_CODE to 0.

The system enters in the wait state, waiting for the user to press the hashtag button.
Whenever this happens, we enter to the state, enter_code waiting for the user to enter the
code. To do that, we activate the Key_read to let know to the keyboard that the # has been
read so it can deactivate that flag, the New_code flag activates the register_bank that is going
to store the user code. We set to one the LED_CODE in order to let know that the user can
enter the code. Also, the GAME_OVER signal is set to 0.

The system enters to another wait state, w_code, in order to wait for the user to enter the
code. Once the user has entered the code, we will know that because he will press the asterisc
button and the output signal Code_Entered will be set to 1. This will produce a change of state,
where we will go to the start_game state.

In this new state, we activate new_game in order to activate the game block and also set the
LED_CODE to 0 in order to show that the code has been entered.

After that, the system will be waiting in the w_game in order to know if the user wins, loses or
ties the game. If the user receives a winner, loser or tie frame, the game has finished and the
system activates again the GAME_OVER signal and returns to the initial state.

In order to run the Main simulation, we just have to put all inputs and all outputs and verify its
functionality according to the state diagram we've seen in class. To do this, we first non active
the nrst so as to start the simulation. Then, it is time to activate the input signals. First, we
activate the hash, we see how key_read and new_code are activated for one clock period.
Also, the game_over signal will go down due to the user has pressed a key and the process
starts and the LED_CODE signal will be active while the user register the code and the game
has not started.
Then, the main block will wait until the full code is entered, it will know it because the signal
code_entered will be activated.
Then we see if code_entered is equal to 1, in consequence led_code is equal to 0 and
new_game activates. Finally, after new game is activated, we just have to active winner, loser
or tie (in this case, we activate loser) and we see that game_over is activated and the system is
ready to go over the same process again.
library ieee;
use ieee.std_logic_1164.all;

entity main_control is
port (
clk50, nrst: in std_logic;
hash: in std_logic;
code_entered: in std_logic;
winner, loser, tie : in std_logic;
key_read, new_code, game_over, new_game, LED_CODE: out std_logic
);
end main_control;

architecture principal of main_control is


type state_type is (m_wait, enter_code, w_code, start_game, w_game );
signal state : state_type;

begin
PROTOCOL_FSM: process (clk50, nrst)
begin

if nrst = '0' then


game_over <= '1';
LED_CODE <= '0';
state <= m_wait;

elsif clk50'EVENT and clk50 = '1' then


case state is
when m_wait =>
if hash = '1' then
state <= enter_code;
end if;
when enter_code =>
LED_CODE <= '1';
GAME_OVER <= '0';
state <= w_code;

when w_code =>


if code_entered = '1' then

state <= start_game;


end if;

when start_game =>


LED_CODE <= '0';
state <= w_game;

when w_game =>


if (winner = '1' or loser = '1' or tie = '1') then
game_over <= '1';
state <= m_wait;
end if;
end case;
end if;
end process;

-- Outputs of the control unit. Always out of the process.

new_code <= '1' when state = enter_code else '0';


key_read <= '1' when state = enter_code else '0';
new_game <= '1' when state = start_game else '0';

end;

You might also like