(vcom-1339) Case statement choices cover only 6 out of 10 cases - vhdl

Case statement choices cover only 6 out of 10 cases for my vending machine code I am getting this error after execution of my very long program in VHDL. However its said that When others => can be used only at the last statement of the code to avoid this particular error however there are many when statements used in the program. How to solve this issue?
library ieee;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity FSMM is
port (CLK : in std_logic; --Clock, active high
RSTn : in std_logic; --Async. Reset, active low
CoinIn : in std_logic_vector (1 downto 0); --Which coin was inserted
gum : out std_logic; --Is Soda dispensed ?
CoinOut : out std_logic_vector (1 downto 0) --Which coin is dispensed?
);
end entity;
architecture behavior of FSMM is
-- add your code here
type state_type is (idle, --start state/reset
put_money, --waiting to enter money
in_5c,in_10c,in_15c,in_20c,in_25c,in_30c,in_35c, --represent the current sum of money after returning change
gum_out --dispence soda can.
); --type of state machine.
signal current_s,next_s: state_type; --current and next state declaration.
begin
process(CLK,RSTn)
begin
if(RSTn = '0') then
current_s <= idle; --defualt state is on RESET
elsif(clk'event and clk = '1') then
current_s <= next_s;
end if;
end process;
--------------------
--FSM process:
process(current_s,CoinIn)
begin
case current_s is
when idle => --state reset or idle
gum <= '0';
CoinOut <= "00";
next_s <= put_money;
------------------------------------------------------
when put_money => --wait for money to be entered
if(CoinIn = "00")then
gum <= '0';
CoinOut <= "00";
next_s <= put_money;
elsif(CoinIn = "01")then --insert 5$
gum <= '0';
CoinOut <= "00";
next_s <= in_5c;
elsif(CoinIn = "10")then --insert 10$
gum <= '0';
CoinOut <= "00";
next_s <= in_10c;
elsif(CoinIn = "11")then --insert 25$
gum <= '0';
CoinOut <= "00";
next_s <= in_25c;
end if;
------------------------------------------------------
when in_5c =>
if(CoinIn = "00") then--stay on the same state
gum <= '0';
CoinOut <= "00";
next_s <= in_5c;
elsif(CoinIn = "01") then--inserted another 1$
gum <= '0';
CoinOut <= "00";
next_s <= in_10c;
elsif(CoinIn = "01") then--inserted another 2$
gum <= '0';
CoinOut <= "00";
next_s <= in_15c;
elsif(CoinIn = "01") then--inserted another 2$
gum <= '0';
CoinOut <= "00";
next_s <= in_20c;
elsif(CoinIn = "01") then--inserted another 2$
gum <= '0';
CoinOut <= "00";
next_s <= in_25c;
elsif(CoinIn = "01") then--inserted another 2$
gum <= '0';
CoinOut <= "00";
next_s <= in_30c;
elsif(CoinIn = "01") then--inserted another 2$
gum <= '0';
CoinOut <= "00";
next_s <= in_35c;
elsif(CoinIn = "01") then--inserted another 2$
gum <= '0';
CoinOut <= "00";
next_s <= gum_out;
end if;
------------------------------------------------------
when in_10c =>
if(CoinIn = "00") then--stay on the same state
gum <= '0';
CoinOut <= "00";
next_s <= in_10c;
elsif(CoinIn = "10") then--inserted another 1$
gum <= '0';
CoinOut <= "00";
next_s <= in_20c;
elsif(CoinIn = "10") then--inserted another 1$
gum <= '0';
CoinOut <= "00";
next_s <= in_30c;
elsif(CoinIn = "10") then--inserted another 1$
gum <= '0';
CoinOut <= "00";
next_s <= gum_out;
end if;
------------------------------------------------------
when in_25c =>
if(CoinIn = "00") then--stay on the same state
gum <= '0';
CoinOut <= "00";
next_s <= in_25c;
elsif(CoinIn = "01") then--inserted another 1$
gum <= '0';
CoinOut <= "00";
next_s <= in_30c;
elsif(CoinIn = "01") then--inserted another 1$
gum <= '0';
CoinOut <= "00";
next_s <= in_35c;
elsif(CoinIn = "01") then--inserted another 1$
gum <= '0';
CoinOut <= "00";
next_s <= gum_out;
end if;
------------------------------------------------------
when gum_out =>
gum <= '1';
CoinOut <= "00";
next_s <= put_money;
end case;
end process;
end behavior;

Your state_type is defined as an enumeration of 10 different values.
But your case statement covers only 6 of them. According to chapter 10.9 of the standard IEEE Std 1076-2008 you need to cover all cases.
This is what the error message tells you.
The solution is to cover all other cases, too, or to insert when others to catch these all together.

Related

Contolling an LCD display in VHDL on Nexys A7 100T

I'm looking to control an external display where the pins are connected to the ports JA and JB on the Nexys A7 100T, I've configured the state machine below according to the instructions in the datasheet but nothing is being displayed. Since this is the first time I'm controlling a display through VHDL, I suspect that either the display is not working or something is not being initialized in the correct manner.
--- Initialization and Data transfer of LCD display---
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity LCD is
generic(
display_lines : std_logic := '0'; --Amount of displaylines: (0 = 1-line, 1 = 2-lines)
font_type : std_logic := '0'; -- Font type: (0 = 5x8 font, 1 = 5x11 font but only available for 1 line mode)
display_on : std_logic := '1'; -- Diplay ON/OFF: (0 = OFF, 1 = ON)
display_off : std_logic := '0';
cursor : std_logic := '0'; -- Cursor ON/OFF: (0 = OFF, 1 = ON)
blink : std_logic := '0'; -- Blink ON/OFF: (0 = OFF, 1 = ON)
I_D : std_logic := '1'; -- Increment/Decrement (0 = Decrement(move left), 1 = Increment(Move right))
shift : std_logic := '1'; -- Shift of display( 0 = Shift not perfomed, 1 = shift done according to I/D)
LCD_freq : integer := (100e6/270e3) - 1 -- Operating frequency of display
);
port(
CLK100MHZ, reset: in std_logic; -- 100MHZ clock and reset signal
LCD_RW: out std_logic; -- Read/write bit for LCD
LCD_RS: out std_logic; -- Register Select for LCD
LCD_E: out std_logic; -- Enable bit for the LCD
data: out std_logic_vector(7 downto 0) -- Data being sent to LCD including setup bits.
);
end entity;
architecture arch of LCD is
Type control is (RESET_1,RESET_2,RESET_3, FUNCTION_SET, DISPLAY_OFF1, DISPLAY_CLEAR, DISPLAY_ON1, ENTRY_MODE_SET, WRITE_T, RETURN_HOME,TOGGLE_E, HOLD);
signal freq_div :std_logic_vector(9 downto 0);
signal clk270 : std_logic; -- LCD clock
signal state, next_cmd: control;
begin
-- Clock for the LCD frequency
process(CLK100MHZ, reset)
begin
if reset = '1' then
freq_div <= (others => '0');
elsif rising_edge(CLK100MHZ) then
if freq_div = LCD_freq then
clk270 <= '1';
freq_div <= (others => '0');
else
clk270 <= '0';
freq_div <= freq_div + 1;
end if; -- freq_div
end if; -- reset
end process;
-- State diagram controlling display
process(CLK100MHZ, reset)
begin
if reset = '1' then
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00111000";
state <= TOGGLE_E;
next_cmd <= RESET_1;
elsif rising_edge(CLK100MHZ) then
if clk270 = '1' then
case state is
when RESET_1 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00111000";
state <= TOGGLE_E;
next_cmd <= RESET_2;
when RESET_2 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00111000";
state <= TOGGLE_E;
next_cmd <= RESET_3;
when RESET_3 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00111000";
state <= TOGGLE_E;
next_cmd <= FUNCTION_SET;
--- Initilization steps done individually ---
when FUNCTION_SET => -- sets the function for the display
LCD_RS <= '0';
LCD_RW <= '0';
data <= "0011" & display_lines & font_type & "00";
LCD_E <= '1'; -- Enables function for display
state <= TOGGLE_E;
next_cmd <= DISPLAY_OFF1;
when DISPLAY_OFF1 => -- Turns the display off
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00001" & display_off & cursor & blink;
state <= TOGGLE_E;
next_cmd <= DISPLAY_CLEAR;
when DISPLAY_CLEAR => -- Clears the display
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00000001";
state <= TOGGLE_E;
next_cmd <= DISPLAY_ON1;
when DISPLAY_ON1 => -- Turns on the display
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00001" & display_on & cursor & blink;
state <= TOGGLE_E;
next_cmd <= ENTRY_MODE_SET;
when ENTRY_MODE_SET => -- Sets the increment and shift
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "000001" & I_D & shift;
state <= TOGGLE_E;
next_cmd <= WRITE_T;
when WRITE_T =>
LCD_RS <= '1';
LCD_RW <= '0';
LCD_E <= '1';
data <= "01000101"; --Letter T
state <= TOGGLE_E;
next_cmd <= RETURN_HOME;
when RETURN_HOME =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW <= '0';
data <= "00000010";
state <= TOGGLE_E;
next_cmd <= WRITE_T;
-- Toggles a falling edge for Enable.
when TOGGLE_E =>
LCD_E <= '1';
state <= HOLD;
when HOLD =>
state <= next_cmd;
end case;
end if; -- clk270kHz
end if; -- reset
end process;
end arch;
The display is of the archetype ST7066U. Any feedback is appreciated.

VHDL: Case Statement choices must cover all possible values of expression

I'm working on project which should convert data from analog to digital with approximation and I have error when i try compile code in Quartus II 9.1sp2 Web Edition which is shown in title with Case Statement in the code below:
architecture behavior of adc is
type state is (reset, state1, state2, state3, state4, state5, state6, state7, state8, state9, state10);
signal nx_state : state;
begin
process (in_clk, rst_n, start)
begin
if(rst_n'event and rst_n='0') then
B_hold <= "1111";
D_out <= "0000";
data_out <= "0000";
hold <= '1';
sample <= '0';
eoc <= '0';
if start = '1' then
nx_state <= state1;
else
nx_state <= reset;
end if;
elsif(in_clk'event and in_clk='1') then
case nx_state is
when state1 => nx_state <= state2;
B_hold <= "0000";
hold <= '0';
sample <= '1';
when state2 => nx_state <= state3;
B_hold <= "1111";
D_out <= "0000";
when state3 => nx_state <= state4;
B_hold(3) <= '0';
D_out(3) <= '1';
data_out(3) <= '1';
when state4 => nx_state <= state5;
if comp_in = '1' then
B_hold(3) <= '0';
D_out(3) <= '1';
data_out(3) <= '1';
else
B_hold(3) <= '1';
D_out(3) <= '0';
data_out(3) <= '0';
end if;
when state5 => nx_state <= state6;
B_hold(2) <= '0';
D_out(2) <= '1';
data_out(2) <= '1';
when state6 => nx_state <= state7;
if comp_in = '1' then
B_hold(2) <= '0';
D_out(2) <= '1';
data_out(2) <= '1';
else
B_hold(2) <= '1';
D_out(2) <= '0';
data_out(2) <= '0';
end if;
when state7 => nx_state <= state8;
B_hold(1) <= '0';
D_out(1) <= '1';
data_out(1) <= '1';
when state8 => nx_state <= state9;
if comp_in = '1' then
B_hold(1) <= '0';
D_out(1) <= '1';
data_out(1) <= '1';
else
B_hold(1) <= '1';
D_out(1) <= '0';
data_out(1) <= '0';
end if;
when state9 => nx_state <= state10;
B_hold(0) <= '0';
D_out(0) <= '1';
data_out(0) <= '1';
when state10 => nx_state <= reset;
if comp_in = '1' then
B_hold(0) <= '0';
D_out(0) <= '1';
data_out(0) <= '1';
else
B_hold(0) <= '1';
D_out(0) <= '0';
data_out(0) <= '0';
end if;
eoc <= '1';
end case;
end if;
end process;
end behavior;
I'm new newbie at vhdl and I don't know what exactly is wrong with the conditions shown above.
Your type includes a state named reset. You need a when for that state.
case nx_state is
when reset =>
Reset is level sensitive. So change
if(rst_n'event and rst_n='0') then
to
if(rst_n='0') then
It is also unusual to have a condition within the reset condition
if start = '1' then
nx_state <= state1;
else
nx_state <= reset;
end if;
Hence, you probably just want:
nx_state <= reset;

Tic-tac-toe in VHDL

I am writing VHDL code of Tic-tac-toe game. In my code, winning state is delayed one turn.
(P.S. I am not very familiar with clock so, I have to set p1_play and p2_play value i.e. 1 or 0 using force in waveform). Can someone please suggest me what makes my program to delay 1 turn.
Thanks you.
(clickable)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tttt1 is
Port (
in1 : in STD_LOGIC;
in2 : in STD_LOGIC;
in3 : in STD_LOGIC;
in4 : in STD_LOGIC;
in5 : in STD_LOGIC;
in6 : in STD_LOGIC;
in7 : in STD_LOGIC;
in8 : in STD_LOGIC;
in9 : in STD_LOGIC;
p1_play : in STD_LOGIC;
p2_play : in STD_LOGIC;
p1_win : out STD_LOGIC;
p2_win : out STD_LOGIC;
out_11 : out STD_LOGIC;
out_12 : out STD_LOGIC;
out_13 : out STD_LOGIC;
out_21 : out STD_LOGIC;
out_22 : out STD_LOGIC;
out_23 : out STD_LOGIC;
out_31 : out STD_LOGIC;
out_32 : out STD_LOGIC;
out_33 : out STD_LOGIC);
end entity tttt1;
architecture Behavioral of tttt1 is
signal temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp21, temp22, temp23, temp24, temp25, temp26, temp27, temp28, temp29 :std_logic :='0';
signal p1win,p2win :std_logic :='0';
signal o11,o12,o13,o21,o22,o23,o31,o32,o33:std_logic :='0';
begin
process(in1,in2,in3,in4,in5,in6,in7,in8,in9)
begin
-----------Start Player 1 Play-------------
if(p1_play ='1' and p2_play='0') then
if (in1= '1') then
temp11 <='1';
temp21 <='0';
o11<='1';
elsif(in2= '1') then
temp12 <='1';
temp22 <='0';
o12<='1';
elsif(in3= '1') then
temp13 <='1';
temp23 <='0';
o13<='1';
elsif(in4= '1') then
temp14 <='1';
temp24 <='0';
o21<='1';
elsif(in5= '1') then
temp15 <='1';
temp25 <='0';
o22<='1';
elsif(in6= '1') then
temp16 <='1';
temp26 <='0';
o23<='1';
elsif(in7= '1') then
temp17 <='1';
temp27 <='0';
o31<='1';
elsif(in8= '1') then
temp18 <='1';
temp28 <='0';
o32<='1';
elsif(in9= '1') then
temp19 <='1';
temp29 <='0';
o33<='1';
end if;
end if;
if ((temp11='1' and temp12='1' and temp13='1') or (temp14='1' and temp15='1' and temp16='1') or (temp17='1' and temp18='1' and temp19='1')
or (temp11='1' and temp14='1' and temp17='1') or (temp12='1' and temp15='1' and temp18='1') or (temp13='1' and temp16='1' and temp19='1')
or (temp11='1' and temp15='1' and temp19='1') or (temp13='1' and temp15='1' and temp17='1')) then
p1win<='1';
end if;
---------------End Player 1 Play---------------
--------------Start Player 2 Play--------------
if(p2_play ='1' and p1_play='0') then
if (in1= '1')then
temp21 <='1';
temp11 <='0';
o11<='1';
elsif(in2= '1') then
temp22 <='1';
temp12 <='0';
o12<='1';
elsif(in3= '1') then
temp23 <='1';
temp13 <='0';
o13<='1';
elsif(in4= '1') then
temp24 <='1';
temp14 <='0';
o21<='1';
elsif(in5= '1') then
temp25 <='1';
temp15 <='0';
o22<='1';
elsif(in6= '1') then
temp26 <='1';
temp16 <='0';
o23<='1';
elsif(in7= '1') then
temp27 <='1';
temp17 <='0';
o31<='1';
elsif(in8= '1') then
temp28 <='1';
temp18 <='0';
o32<='1';
elsif(in9= '1') then
temp29 <='1';
temp19 <='0';
o33<='1';
end if;
end if;
if( (temp21='1' and temp22='1' and temp23='1') or (temp24='1' and temp25='1' and temp26='1') or (temp27='1' and temp28='1' and temp29='1')
or (temp21='1' and temp24='1' and temp27='1') or (temp22='1' and temp25='1' and temp28='1') or (temp23='1' and temp26='1' and temp29='1')
or (temp21='1' and temp25='1' and temp29='1') or (temp23='1' and temp25='1' and temp27='1')) then
p2win<='1';
end if;
---------------End Player 2 Play---------------
end process;
p1_win <= p1win;
p2_win <= p2win;
out_11 <= o11;
out_12 <= o12;
out_13 <= o13;
out_21 <= o21;
out_22 <= o22;
out_23 <= o23;
out_31 <= o31;
out_32 <= o32;
out_33 <= o33;
end Behavioral;
The cause of your delay on seeing p2_win is that temp11 through temp13, temp21 through temp 23 and temp31 through temp33 are not in the process sensitivity list (nor should they be). The update of p1_win or p2_win doesn't occur until there's an event on signal in the process sensitivity list, in this case a transistion on in3 and in9.
Making the assignments to the two win outputs separate concurrent signal assigments gets the delay right:
The modified code (With formatting for readability) looks like:
library ieee;
use ieee.std_logic_1164.all;
entity tttt1 is
port (
in1: in std_logic;
in2: in std_logic;
in3: in std_logic;
in4: in std_logic;
in5: in std_logic;
in6: in std_logic;
in7: in std_logic;
in8: in std_logic;
in9: in std_logic;
p1_play: in std_logic;
p2_play: in std_logic;
p1_win: out std_logic;
p2_win: out std_logic;
out_11: out std_logic;
out_12: out std_logic;
out_13: out std_logic;
out_21: out std_logic;
out_22: out std_logic;
out_23: out std_logic;
out_31: out std_logic;
out_32: out std_logic;
out_33: out std_logic
);
end entity tttt1;
architecture behavioral of tttt1 is
signal temp11, temp12,
temp13, temp14,
temp15, temp16,
temp17, temp18,
temp19, temp21,
temp22, temp23,
temp24, temp25,
temp26, temp27,
temp28, temp29: std_logic := '0';
signal p1win,p2win: std_logic := '0';
signal o11,o12,o13,o21,
o22,o23,o31,o32,
o33: std_logic := '0';
begin
process (in1,in2,in3,in4,in5,in6,in7,in8,in9)
begin
-----------Start Player 1 Play-------------
if p1_play = '1' and p2_play = '0' then
if in1 = '1' then
temp11 <= '1';
temp21 <= '0';
o11 <= '1';
elsif in2 = '1' then
temp12 <= '1';
temp22 <= '0';
o12 <= '1';
elsif in3 = '1' then
temp13 <= '1';
temp23 <= '0';
o13 <= '1';
elsif in4 = '1' then
temp14 <= '1';
temp24 <= '0';
o21 <= '1';
elsif in5 = '1' then
temp15 <= '1';
temp25 <= '0';
o22 <= '1';
elsif in6 = '1' then
temp16 <= '1';
temp26 <= '0';
o23<= '1';
elsif in7 = '1' then
temp17 <= '1';
temp27 <= '0';
o31<= '1';
elsif in8 = '1' then
temp18 <= '1';
temp28 <= '0';
o32 <= '1';
elsif in9 = '1' then
temp19 <= '1';
temp29 <= '0';
o33 <= '1';
end if;
end if;
-- if (temp11 = '1' and temp12 = '1' and temp13 = '1') or
-- (temp14 = '1' and temp15 = '1' and temp16 = '1') or
-- (temp17 = '1' and temp18 = '1' and temp19 = '1') or
-- (temp11 = '1' and temp14 = '1' and temp17 = '1') or
-- (temp12 = '1' and temp15 = '1' and temp18 = '1') or
-- (temp13 = '1' and temp16 = '1' and temp19 = '1') or
-- (temp11 = '1' and temp15 = '1' and temp19 = '1') or
-- (temp13 = '1' and temp15 = '1' and temp17 = '1') then
--
-- p1win <= '1';
--
-- end if;
---------------End Player 1 Play---------------
--------------Start Player 2 Play--------------
if p2_play = '1' and p1_play = '0' then
if in1 = '1' then
temp21 <= '1';
temp11 <= '0';
o11 <= '1';
elsif in2 = '1' then
temp22 <= '1';
temp12 <= '0';
o12 <= '1';
elsif in3 = '1' then
temp23 <= '1';
temp13 <= '0';
o13 <= '1';
elsif in4 = '1' then
temp24 <= '1';
temp14 <= '0';
o21 <= '1';
elsif in5 = '1' then
temp25 <= '1';
temp15 <= '0';
o22 <= '1';
elsif in6 = '1' then
temp26 <= '1';
temp16 <= '0';
o23 <= '1';
elsif in7 = '1' then
temp27 <= '1';
temp17 <= '0';
o31 <= '1';
elsif in8 = '1' then
temp28 <= '1';
temp18 <= '0';
o32 <= '1';
elsif in9 = '1' then
temp29 <= '1';
temp19 <= '0';
o33 <= '1';
end if;
end if;
-- if (temp21 = '1' and temp22 = '1' and temp23 = '1') or
-- (temp24 = '1' and temp25 = '1' and temp26 = '1') or
-- (temp27 = '1' and temp28 = '1' and temp29 = '1') or
-- (temp21 = '1' and temp24 = '1' and temp27 = '1') or
-- (temp22 = '1' and temp25 = '1' and temp28 = '1') or
-- (temp23 = '1' and temp26 = '1' and temp29 = '1') or
-- (temp21 = '1' and temp25 = '1' and temp29 = '1') or
-- (temp23 = '1' and temp25 = '1' and temp27 = '1') then
--
-- p2win <= '1';
--
-- end if;
---------------End Player 2 Play---------------
end process;
p1win <= (temp11 and temp12 and temp13) or
(temp14 and temp15 and temp16) or
(temp17 and temp18 and temp19) or
(temp11 and temp14 and temp17) or
(temp12 and temp15 and temp18) or
(temp13 and temp16 and temp19) or
(temp11 and temp15 and temp19) or
(temp13 and temp15 and temp17);
p2win <= (temp21 and temp22 and temp23) or
(temp24 and temp25 and temp26) or
(temp27 and temp28 and temp29) or
(temp21 and temp24 and temp27) or
(temp22 and temp25 and temp28) or
(temp23 and temp26 and temp29) or
(temp21 and temp25 and temp29) or
(temp23 and temp25 and temp27);
p1_win <= p1win;
p2_win <= p2win;
out_11 <= o11;
out_12 <= o12;
out_13 <= o13;
out_21 <= o21;
out_22 <= o22;
out_23 <= o23;
out_31 <= o31;
out_32 <= o32;
out_33 <= o33;
end architecture behavioral;
The functional changes are limited to making the win output assignments concurrent signal assignment statements.
A test bench was used to reproduce the stimuli in your linked waveform:
library ieee;
use ieee.std_logic_1164.all;
entity tttt1_tb is
end entity;
architecture foo of tttt1_tb is
signal in1: std_logic := '0';
signal in2: std_logic := '0';
signal in3: std_logic := '0';
signal in4: std_logic := '0';
signal in5: std_logic := '0';
signal in6: std_logic := '0';
signal in7: std_logic := '0';
signal in8: std_logic := '0';
signal in9: std_logic := '0';
signal p1_play: std_logic := '0';
signal p2_play: std_logic := '0';
signal p1_win: std_logic;
signal p2_win: std_logic;
signal out_11: std_logic;
signal out_12: std_logic;
signal out_13: std_logic;
signal out_21: std_logic;
signal out_22: std_logic;
signal out_23: std_logic;
signal out_31: std_logic;
signal out_32: std_logic;
signal out_33: std_logic;
begin
DUT:
entity work.tttt1
port map (
in1 => in1,
in2 => in2,
in3 => in3,
in4 => in4,
in5 => in5,
in6 => in6,
in7 => in7,
in8 => in8,
in9 => in9,
p1_play => p1_play,
p2_play => p2_play,
p1_win => p1_win,
p2_win => p2_win,
out_11 => out_11,
out_12 => out_12,
out_13 => out_13,
out_21 => out_21,
out_22 => out_22,
out_23 => out_23,
out_31 => out_31,
out_32 => out_32,
out_33 => out_33
);
STIMULI:
process
begin
in1 <= '1';
p1_play <= '1';
wait for 100 ns;
in1 <= '0';
in2 <= '1';
p1_play <= '0';
p2_play <= '1';
wait for 100 ns;
in2 <= '0';
in9 <= '1';
p1_play <= '1';
p2_play <= '0';
wait for 100 ns;
in5 <= '1';
in9 <= '0';
p1_play <= '0';
p2_play <= '1';
wait for 100 ns;
in5 <= '0';
in7 <= '1';
p1_play <= '1';
p2_play <= '0';
wait for 100 ns;
in7 <= '0';
in8 <= '1';
p1_play <= '0';
p2_play <= '1';
wait for 100 ns;
in3 <= '1';
in8 <= '0';
p1_play <= '1';
p2_play <= '0';
wait for 100 ns;
wait;
end process;
end architecture;
There's a missing rule check to not allow a player to capture a square obliviously. That rule should be implemented as well as a method for clearing a game. The game state is held in inferred latches, that might be more widely synthesis eligible if the latches were describe in separate process driven by a single input. There would also be an expectation that the inputs are debounced.
Because there'd be a hardware expectation that an input occurs while the value of p1_play and p2_play is stable, it is possible to use a clock and pass input events (one clock in duration). It used to be common to have these sorts of games describe asynchronously in hardware implementations (think '70s and '80s).

Train Ticket Machine in VHDL

I am new in VHDL. I try to create train ticket machine using vhdl. It have 3 destination and all destination have fee. When user insert money with same of fee, ticket will out and no change but if user enter extra money than fee, ticket will out also with change.When i run the simulation all output does not appear correctly but only come out with uuu. Anybody can help me with my code below, please.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity trainticket_machine is
PORT( Clock,Reset,Cancel : IN STD_LOGIC;
RM1,RM2,RM5 : IN STD_LOGIC;
KL_station,Mid_station,Klang_station : IN STD_LOGIC;
Ticket : OUT STD_LOGIC;
Change,Retrn : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
Money_sum : INOUT STD_LOGIC_VECTOR (3 DOWNTO 0)
);
end trainticket_machine;
architecture Behavioral of trainticket_machine is
TYPE state IS (S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,Cancl,waiting1,waiting2,waiting3,KL_Ticket,Mid_Ticket,Shah_Ticket);
SIGNAL p_state,Train_state: STATE;
BEGIN
PROCESS(Reset,Clock)
BEGIN
IF (Reset = '1') THEN
p_state <= S0;
Ticket <= '0';
Retrn <= "0000";
Money_sum <= "ZZZZ";
ELSIF (Clock'EVENT AND Clock = '1') THEN
p_state <= Train_state;
END IF;
END PROCESS;
PROCESS (p_state,Cancel,RM1,RM2,RM5,KL_station,Mid_station,Klang_station)
BEGIN
CASE p_state IS
WHEN S0 =>
Money_sum <= "0000";
Change <= "0000";
IF (KL_station = '1') THEN Train_state <= waiting1;
ELSIF(Mid_station = '1') THEN Train_state <= waiting2;
ELSIF(Klang_station = '1') THEN Train_state <= waiting3;
ELSE Train_state <= S0;
END IF;
WHEN waiting1 =>
Ticket <= '0';
Change <= "0000";
IF (RM1 = '1') THEN Train_state <= S1;
ELSIF (RM2 = '1') THEN Train_state <= S2;
ELSIF (RM5 = '1') THEN Train_state <= S3;
ELSIF (Money_sum >= 2) THEN train_state <= KL_Ticket;
ELSIF (Cancel = '1') THEN Train_state <= Cancl;
ELSE Train_state <= waiting1;
END IF;
WHEN waiting2 =>
Ticket <= '0';
Change <= "0000";
IF (RM1 = '1') THEN Train_state <= S4;
ELSIF (RM2 = '1') THEN Train_state <= S5;
ELSIF (RM5 = '1') THEN Train_state <= S6;
ELSIF (Money_sum >= 4) THEN train_state <= Mid_Ticket;
ELSIF (Cancel = '1') THEN Train_state <= Cancl;
ELSE Train_state <= waiting2;
END IF;
WHEN waiting3 =>
Ticket <= '0';
Change <= "0000";
IF (RM1 = '1') THEN Train_state <= S7;
ELSIF (RM2 = '1') THEN Train_state <= S8;
ELSIF (RM5 = '1') THEN Train_state <= S9;
ELSIF (Money_sum >= 6) THEN train_state <= Shah_Ticket;
ELSIF (Cancel = '1') THEN Train_state <= Cancl;
END IF;
WHEN S1 =>
IF (RM1 <= '1' AND RM2 <= '0' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 1;
ELSE Train_state <= waiting1;
END IF;
WHEN S2 =>
IF (RM1 <= '1' AND RM2 <= '1' AND RM5 <= '0') THEN
Ticket <= '1';
Change <= "0000";
Money_sum <= Money_sum + 2;
ELSE Train_state <= waiting1;
END IF;
WHEN S3 =>
IF (RM1 <= '0' AND RM2 <= '0' AND RM5 <= '1') THEN
Ticket <= '1';
Change <= "0001";
Money_sum <= Money_sum + 5;
ELSE Train_state <= waiting1;
END IF;
WHEN S4 =>
IF (RM1 <= '1' AND RM2 <= '0' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 1;
ELSE Train_state <= waiting2;
END IF;
WHEN S5 =>
IF (RM1 <= '0' AND RM2 <= '1' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 2;
ELSE Train_state <= waiting2;
END IF;
WHEN S6 =>
IF (RM1 <= '0' AND RM2 <= '0' AND RM5 <= '1') THEN
Ticket <= '0';
Change <= "0001";
Money_sum <= Money_sum + 5;
ELSE Train_state <= waiting2;
END IF;
WHEN S7 =>
IF (RM1 <= '1' AND RM2 <= '0' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 1;
ELSE Train_state <= waiting3;
END IF;
WHEN S8 =>
IF (RM1 <= '0' AND RM2 <= '1' AND RM5 <= '0') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 2;
ELSE Train_state <= waiting3;
END IF;
WHEN S9 =>
IF (RM1 <= '0' AND RM2 <= '0' AND RM5 <= '1') THEN
Ticket <= '0';
Change <= "0000";
Money_sum <= Money_sum + 5;
ELSE Train_state <= waiting3;
END IF;
WHEN KL_Ticket =>
Ticket <= '1';
Change <= Money_sum - 2;
Train_state <= waiting1;
WHEN Mid_Ticket =>
Ticket <= '1';
Change <= Money_sum - 4;
Train_state <= waiting2;
WHEN Shah_Ticket =>
Ticket <= '1';
Change <= Money_sum - 6;
Train_state <= waiting3;
WHEN Cancl =>
IF (Cancel <= '1') THEN
Retrn <= Money_sum;
ELSE Train_state <= S0;
END IF;
END CASE;
END PROCESS;
end Behavioral;
------------------------------simulation----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
ENTITY trainticket_machine_tb IS
END trainticket_machine_tb;
ARCHITECTURE behavior OF trainticket_machine_tb IS
Signal Clock,Reset,Cancel,RM1,RM2,RM5,KL_station,Mid_station,Klang_station : std_logic := '0';
Signal Ticket : std_logic ;
signal Change,Retrn,Money_sum : std_logic_vector(3 downto 0);
constant Clock_period : time := 10 ns;
BEGIN
uut: entity work.trainticket_machine PORT MAP (
Clock => Clock,
Reset => Reset,
Cancel => Cancel,
RM1 => RM1,
RM2 => RM2,
RM5 => RM5,
KL_station => KL_station,
Mid_station => Mid_station,
Klang_station => Klang_station,
Ticket => Ticket,
Change => Change,
Retrn => Retrn,
Money_sum => Money_sum
);
Clock_process :process
begin
Clock <= '0';
wait for Clock_period/2;
Clock <= '1';
wait for Clock_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for Clock_period*2;
Reset <= '1';
wait for Clock_period;
Reset <= '0';
wait for Clock_period;
Cancel <= '1';
wait for Clock_period;
Cancel <= '0';
wait for Clock_period;
KL_station <= '1';
wait for Clock_period;
KL_station <= '0';
wait for Clock_period;
Mid_station <= '1';
wait for Clock_period;
Mid_station <= '0';
wait for Clock_period;
Klang_station <= '1';
wait for Clock_period;
Klang_station <= '0';
wait for Clock_period;
RM1 <= '1';
wait for Clock_period;
RM1 <= '0';
wait for Clock_period;
RM2 <= '1';
wait for Clock_period;
RM2 <= '0';
wait for Clock_period;
RM5 <= '1';
wait for Clock_period;
RM5 <= '0';
wait for Clock_period;
wait;
end process;
END;
Starting with the first problem you describe: since you are seeing only 'U's, maybe your outputs were never assigned any value. Did you remember to force Reset to '1' in the beginning of the simulation?
Now let's take a look at the state machine logic itself, which has many problems. First thing: you should differentiate between combinational logic and registered state. By state I mean values that must be kept in registers of flip-flops, between the clock transitions.
This is important because for each process you will have to decide whether it is combinational or registered. If the process is registered, it must be sensitive to your clock. If the process is combinational, it cannot have any statements that woud imply keeping state information.
So the first suggestion is to go through your code, and decide the nature of each process you have. You may have to create a few more processes, it's ok. From your code, it looks like the signal money_sum is state information, and therefore it should be updated on the rising edge of clock.
The second suggestion is: if you have an output that depends only on the current state (maybe your signal ticket), you need to assign a value to this signal on every condition of your case statement. Try removing the line Ticket <= '0'; from your first process and see what happens.
Third, please use more descriptive names for your states and signals, it is really hard to understand what is going on from names like S0, S1, S2, RM1, RM2, and RM5.
Finally, it would be really helpful to have some assertions in your testbench code. For instance, after every wait for Clock_period;, you could check your outputs to make sure they match what you expected:
Reset <= '1';
wait for Clock_period;
assert ticket = '0' report "Wrong value for 'ticket' after reset";
assert change = "0000" report "Wrong value for 'change' after reset";
assert retrn = "0000" report "Wrong value for 'retrn' after reset";
assert money_sum = "0000" report "Wrong value for 'money_sum' after reset";

VHDL Code for State Machine

I am attempting to write a Successive Approximation Register in VHDL for an ADC. I am making it a state machine. I am just a little unsure about my code in the final State block (current_state = S_LSB). Is this code valid? Is there a better way to reset DigitalOutTemp and OutTemp before going back to state one?
NOTE The value of Comparator depends on the DigitalOutTemp output after it goes through a Digital to Analog Converter.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY SARegister IS
PORT (
Comparator, Clock : IN std_logic;
DigitalOutFinal, DigitalOutTemp : OUT std_logic_vector (13 downto 0)
);
END;
ARCHITECTURE Behavioural OF SARegister IS
CONSTANT S_MSB : STD_LOGIC_VECTOR(3 downto 0) := "0000";
CONSTANT S_TWELVE : STD_LOGIC_VECTOR(3 downto 0) := "0001";
CONSTANT S_ELEVEN : STD_LOGIC_VECTOR(3 downto 0) := "0010";
CONSTANT S_TEN : STD_LOGIC_VECTOR(3 downto 0) := "0011";
CONSTANT S_NINE : STD_LOGIC_VECTOR(3 downto 0) := "0100";
CONSTANT S_EIGHT : STD_LOGIC_VECTOR(3 downto 0) := "0101";
CONSTANT S_SEVEN : STD_LOGIC_VECTOR(3 downto 0) := "0110";
CONSTANT S_SIX : STD_LOGIC_VECTOR(3 downto 0) := "0111";
CONSTANT S_FIVE : STD_LOGIC_VECTOR(3 downto 0) := "1000";
CONSTANT S_FOUR : STD_LOGIC_VECTOR(3 downto 0) := "1001";
CONSTANT S_THREE : STD_LOGIC_VECTOR(3 downto 0) := "1010";
CONSTANT S_TWO : STD_LOGIC_VECTOR(3 downto 0) := "1011";
CONSTANT S_ONE : STD_LOGIC_VECTOR(3 downto 0) := "1100";
CONSTANT S_LSB : STD_LOGIC_VECTOR(3 downto 0) := "1101";
SIGNAL Next_state : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Current_state : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL OutTemp : STD_LOGIC_VECTOR(13 DOWNTO 0);
BEGIN
PROCESS (Clock)
BEGIN
IF (rising_edge (Clock)) THEN
Current_state <= Next_state;
END IF;
END PROCESS;
PROCESS (Current_state, Comparator)
BEGIN
Next_state <= Current_state;
DigitalOutTemp <= "10000000000000";
OutTemp <= "10000000000000";
DigitalOutFinal <= "00000000000000";
IF (Current_state = S_MSB) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(13) <= '0';
OutTemp(13) <= '0';
END IF;
DigitalOutTemp(12) <='1';
OutTemp(12) <= '1';
Next_state <= S_TWELVE;
ELSIF (Current_state = S_TWELVE) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(12) <= '0';
OutTemp(12) <= '0';
END IF;
DigitalOutTemp(11) <='1';
OutTemp(11) <= '1';
Next_state <= S_ELEVEN;
ELSIF (Current_state = S_ELEVEN) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(11) <= '0';
OutTemp(11) <= '0';
END IF;
DigitalOutTemp(10) <='1';
OutTemp(10) <= '1';
Next_state <= S_TEN;
ELSIF (Current_state = S_TEN) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(10) <= '0';
OutTemp(10) <= '0';
END IF;
DigitalOutTemp(9) <='1';
OutTemp(9) <= '1';
Next_state <= S_NINE;
ELSIF (Current_state = S_NINE) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(9) <= '0';
OutTemp(9) <= '0';
END IF;
DigitalOutTemp(8) <='1';
OutTemp(8) <= '1';
Next_state <= S_EIGHT;
ELSIF (Current_state = S_EIGHT) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(8) <= '0';
OutTemp(8) <= '0';
END IF;
DigitalOutTemp(7) <='1';
OutTemp(7) <= '1';
Next_state <= S_SEVEN;
ELSIF (Current_state = S_SEVEN) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(7) <= '0';
OutTemp(7) <= '0';
END IF;
DigitalOutTemp(6) <='1';
OutTemp(6) <= '1';
Next_state <= S_SIX;
ELSIF (Current_state = S_SIX) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(6) <= '0';
OutTemp(6) <= '0';
END IF;
DigitalOutTemp(5) <='1';
OutTemp(5) <= '1';
Next_state <= S_FIVE;
ELSIF (Current_state = S_FIVE) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(5) <= '0';
OutTemp(5) <= '0';
END IF;
DigitalOutTemp(4) <='1';
OutTemp(4) <= '1';
Next_state <= S_FOUR;
ELSIF (Current_state = S_FOUR) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(4) <= '0';
OutTemp(4) <= '0';
END IF;
DigitalOutTemp(3) <='1';
OutTemp(3) <= '1';
Next_state <= S_THREE;
ELSIF (Current_state = S_THREE) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(3) <= '0';
OutTemp(3) <= '0';
END IF;
DigitalOutTemp(2) <='1';
OutTemp(2) <= '1';
Next_state <= S_TWO;
ELSIF (Current_state = S_TWO) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(2) <= '0';
OutTemp(2) <= '0';
END IF;
DigitalOutTemp(1) <='1';
OutTemp(1) <= '1';
Next_state <= S_ONE;
ELSIF (Current_state = S_ONE) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(1) <= '0';
OutTemp(1) <= '0';
END IF;
DigitalOutTemp(0) <='1';
OutTemp(0) <= '1';
Next_state <= S_LSB;
ELSIF (Current_state = S_LSB) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(0) <= '0';
OutTemp(0) <= '0';
END IF;
DigitalOutFinal <= OutTemp;
DigitalOutTemp <= "10000000000000";
OutTemp <= "10000000000000";
Next_state <= S_MSB;
END IF;
END PROCESS;
END;
Its hard to tell what your code is trying to accomplish, so I thought I'd make some general observations that might help you along.
There is a lot of needless repetition in your code that you can fix by using a counter to index your bits rather than a hard coded index in each state, for example using a counter idx that counts from your MSB to LSB you can do:
...
elsif (current_state = COMPARE) then
OutTemp(idx) <= comparator;
if idx > 0 then
OutTemp(idx-1) <= '1';
idx <= idx - 1;
next_state <= current_state;
else
idx <= MSB;
next_state <= idle;
end if;
end if;
This assumes you want to set OutTemp(idx-1) in the previous state, which strikes me as a bit pointless, but maybe its required by your external hardware...
You have also duplicated your OutTemp by assigning to both a signal and a port, I would remove all your assignments to the port DigitalOutTemp and instead add the following to your clocked process:
process (clock)
begin
if rising_edge(clock) then
Current_state <= Next_state;
DigitalOutTemp <= OutTemp;
end if;
end process;
This will set DigitalOutTemp synchronously, if you dont want this you can set it outside of the clocked process instead, but I would advise you to set it synchronously to avoid glitches.
To answer your question, the final state:
ELSIF (Current_state = S_LSB) THEN
IF (Comparator = '0') THEN
DigitalOutTemp(0) <= '0';
OutTemp(0) <= '0';
END IF;
DigitalOutFinal <= OutTemp;
DigitalOutTemp <= "10000000000000";
OutTemp <= "10000000000000";
Next_state <= S_MSB;
END IF;
.. will just set DigitalOutTemp to "10000000000000" and DigitalOutFinal to whatever was in OutTemp in the previous state. It appears that you expect OutTemp to have been updated by the assignment to OutTemp(0) further up, but this wont be the case. The assignment to OutTemp(0) is scheduled for the end of the process; it isn't visible immediately.
The assignments to OutTemp(0) and DigitalOutTemp(0) in the IF statement will do nothing as their scheduled writes are cancelled by your assignments to them further down.
So to answer your question, it looks like valid code in that it will probably compile and synthesize, but it wont exhibit the behaviour you seem to expect.
Hope this helps.

Resources