How to make a key generated, 7 segment display, output persist after the key is released? [VHDL] - vhdl

I'm trying to read input from the keypad and I want the number entered by the user to persist on a 7 segment display until another key is pressed.
Currently, the 7 segment display output disappears when the key is released. How can I make the 7 segment display output persist?
This is my entire code :
ARCHITECTURE Behavioral OF keypad IS
SIGNAL t1, t2, t3, t4: STD_LOGIC_VECTOR (1 TO 4) := "1111";
SIGNAL curr : STD_LOGIC_VECTOR(1 TO 4) := "0111";
BEGIN
proc_1: PROCESS
BEGIN
WAIT UNTIL rising_edge(clk);
IF curr <= "0111" THEN t1<= row ;
curr <= "1011";
ELSIF curr <= "1011" THEN t2<= row ;
curr <= "1101";
ELSIF curr <= "1101" THEN t3<= row ;
curr <= "1110";
ELSIF curr <= "1110" THEN t4<= row ;
curr <= "0111";
ELSE
curr <= "0111";
END IF ;
END PROCESS ;
proc_2: PROCESS (t1, t2, t3, t4)
BEGIN
hit <= '1';
IF t1(1) = '0' THEN sevenseg <= "1001111" ; --1
ELSIF t1(2) = '0' THEN sevenseg <= "1001100" ; --4
ELSIF t1(3) = '0' THEN sevenseg <= "0001111" ; --7
ELSIF t1(4) = '0' THEN sevenseg <= "1111111" ; --*
ELSIF t2(1) = '0' THEN sevenseg <= "0010010" ; --2
ELSIF t2(2) = '0' THEN sevenseg <="0100100" ; --5
ELSIF t2(3) = '0' THEN sevenseg <= "0000000" ; --8
ELSIF t2(4) = '0' THEN sevenseg <= "0000001" ; --0
ELSIF t3(1) = '0' THEN sevenseg <= "0000110" ; --3
ELSIF t3(2) = '0' THEN sevenseg <= "0100000" ; --6
ELSIF t3(3) = '0' THEN sevenseg <= "0000100" ; --9
ELSIF t3(4) = '0' THEN sevenseg <= "1111111" ; --#
ELSIF t4(1) = '0' THEN sevenseg <= "0001000" ; --A
ELSIF t4(2) = '0' THEN sevenseg <= "1111111" ; --B
ELSIF t4(3) = '0' THEN sevenseg <= "0110001" ; --C
ELSIF t4(4) = '0' THEN sevenseg <= "1111111" ; --D
ELSE
hit <= '0';
END IF;
END PROCESS;
col <= curr ;
END Behavioral ;

Related

Testbench for FSM

I'm trying to implement a testbench for the following fsm in created in vhdl. The problem is that currently, I'm not seeing any state transitions in the test bench. The simulation stays at state 0.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_Challenge is
Port ( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end FPGA_Challenge;
architecture Behavioral of FPGA_Challenge is
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x:std_logic;
signal y:std_logic;
signal count : integer:= 0;
--signal tmp: std_logic:= '1';
begin
process(clk_in, reset)
begin
if rising_edge(clk_in)then
if reset = '1'then -- Goes back to known state (state 0)
state <= s0;
count <= 0;
else
count <= count + 1;
case state is
-- Initial state- if button is pressed, then LED is lit and machine goes to state 2, if not it stays in state 1
when s0 =>
if (button <= '1') then
led <= '1';
state <= s1;
else
state <= s0;
led <= '0'; --is this necessary?
end if;
-- Beginning of preamble detection(states 1-17)
-- Count = ((freq in) / (freq out))/ 2 -1 = (100 MHz/ 2 MHz)/ 2 -1 = 50/2 - 1 (due to 50% duty cycle)
when s1=> -- do I need to put led = '1' in each state because it stays on ?
if (count = 25 -1) then
count <= 0;
if (data_line = '1')then
y <= '0';
-- led = '1';
state <= s2;
else
-- led = '1';
y <= '0';
state <= s1;
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s2 =>
if (count = 25-1) then
count <= 0;
if (data_line = '0')then
y <= '0';
-- led = '1';
state <= s3;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s3 =>
if (count = 25-1)then
count <= 0; ----reinitializes count
if (data_line <= '1')then
y <= '0';
-- led = '1';
state <= s4;
else
state <= s1;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s4 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s5;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s5 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s6;
else
state <= s4;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s6 =>
if (count= 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s7 =>
if (count = 25-1)then
count<= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s8 =>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
-- led = '1';
state <= s9;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s9 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s10;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s10=>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
--led = '1';
state <= s11;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s11 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s12;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s12 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s13;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s13 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s14;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s14 =>
if (count = 25-1)then
count <=0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s15;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s15 =>
if (count = 25-1)then
count <=0;
if (data_line <='0') then
y <= '0';
-- led = '1';
state <= s16;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s16 =>
if (count = 25-1) then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s17;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s17 =>
if (count = 25-1)then
count <= 0;
if (data_line ='1')then
y <= '1';
-- led = '1';
state <= s18;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s18 => -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s19;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s19=> -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s0;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when others=>
null;
end case;
end if;
end if;
end process;
end architecture;
The following is the testbench I have so far. I have internal signals such as y(output for each state), and count(counter for how long I'm in a state) that I probably should be using as drivers in the testbench. Any input is appreciated
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_tb is
-- Port ( );
end FPGA_tb;
architecture Behavioral of FPGA_tb is
component FPGA_Challenge is
Port( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end component;
signal led : STD_LOGIC;
signal clk_in : STD_LOGIC; -- 100 MHZ internal clock
signal reset : STD_LOGIC; -- is reset necessary
signal button : STD_LOGIC;
signal data_line : STD_LOGIC;
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x,y: std_logic;
signal count : integer:= 0;
begin
UUT: FPGA_Challenge
PORT MAP(
led => led,
clk_in => clk_in,
reset => reset,
button => button,
data_line => data_line
);
Testing: Process
begin
--wait until rising_edge(clk_in);
--wait until rising_edge(clk_in);
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '0';
button <= '1';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '1';
WAIT For 10ns;
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
end process;
end Behavioral;
Try this in the testbench to have a running clock and proper reset
signal clk_in : STD_LOGIC := '1'; -- 100 MHZ internal clock
signal reset : STD_LOGIC := '1'; -- is reset necessary
clk_in <=NOT clk_in after 10ns;
reset <= 0 after 30ns;
play with button after the reset. that is, from 40ns

Can't find the issues and latches are generated

My code generates two latches, could please someone help me finding why?
According to Xilinx ISE latches are generated because of "try_counter" which is a counter for how many times you get a numeric sequence wrong. (which is the main point of my code).
I don't know what else to do.
entity moore is
Port ( badgeSx : in STD_LOGIC;
badgeDx : in STD_LOGIC;
col : in std_logic_vector (1 to 3);
row : in std_logic_vector (1 to 4);
clk : in std_logic;
rst : in std_logic;
unlock : out STD_LOGIC
);
end moore;
architecture Behavioral of moore is
type stato is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
signal current_state,next_state : stato;
signal badge : std_logic_vector(1 downto 0);
signal count, new_count: integer range 0 to 28;
signal temp_unlock : std_logic :='0';
signal timeover : std_logic :='0';
begin
badge <= badgeDx & badgeSx; --concatenazione dei badge
--processo sequenziale
current_state_register: process(clk)
begin
if rising_edge(clk) then
if (rst = '1') then
current_state <= s0;
count <= 0;
else
current_state <= next_state;
count <= new_count;
end if;
end if;
end process;
process (current_state,badge,col,row,timeover)
variable try_counter: integer range 0 to 3;
begin
case current_state is
when s0 =>
try_counter := 0;
temp_unlock <= '0';
unlock <='0';
if(badge ="01" and row = "0000" and col = "000" ) then
next_state <= s1;
else
next_state <= s0;
end if;
when s1 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s2 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
else
next_state <= s3;
end if;
when s3 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s4 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
else
next_state <= s5;
end if;
when s5 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s6 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
else
next_state <= s7;
end if;
when s7 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s8 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
else
next_state <= s9;
end if;
when s9 =>
temp_unlock <= '0';
unlock <= '1';
if (badge = "10") then
next_state <= s0;
else
next_state <= s5;
end if;
when others =>
next_state <= s0;
end case;
end process;
Contatore_TIMER : process(temp_unlock,count)
begin
if temp_unlock = '1' then
if count = 28 then
new_count<=0;
timeover<='1';
else
new_count<=count+1;
timeover<='0';
end if;
else
new_count<=0;
timeover <= '0';
end if;
end process;
end Behavioral;
The code nearly works as expected (I mean it compiles and I don't get any error) but the RTL schematic isn't what it is supposed to be since it synthesises latches in the process.
In the apparently combinatorial process with process (current_state,badge,col,row,timeover), the variable try_counter is used to store information (sequential behaviour), which is only updated when process evaluation is triggered. This will very likely to generate the 2 latches, which matches the value range from 0 to 3 for try_counter.
To fix this, you can define try_counter as a signal, and include it in the sensitivity list for the process.
Having try_counter as a signal will also ease debugging, since the current state can easily be inspected in waveforms.

Counter with a final state machine structure in VHDL. QUARTUS

I've produced this VHDL code and testing it with a VWF file seems that it works. But the finite state machine that my code produces (I can see it using the QUARTUS tool "state machine viewer") it seems to be wrong. In this FSM seems that in each state it is possible to reach any one else state.
According to my project goals I need a counter that counts from zero to nine and it changes its value according to the value of two input signals w0 and w1. If w0 and w1 are both zero, the counter attends in its current state, if w0 is 0 and w1 is 1 the counter increases by one, if w0 is 1 and w1 is 0 the counter increases by two, if w0 and w1 are both 1 the counter decrements by one. There are also a clock signal and a reset signal.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY counter IS
PORT(clk, reset :in std_logic;
w :in std_logic_vector(1 DOWNTO 0);
cont :out std_logic_vector(3 DOWNTO 0););
END;
ARCHITECTURE arch_counter OF counter IS
TYPE state IS (zero, one, two, three, four, five, six, seven, eight, nine);
SIGNAL numbCorr, numbFuture :state;
BEGIN
PROCESS(w, numbCorr)
BEGIN
CASE numbCorr IS
WHEN zero => IF w = "00" THEN numbFuture <= zero;
ELSIF w = "01" THEN numbFuture <= one;
ELSIF w = "10" THEN numbFuture <= two;
ELSIF w = "11" THEN numbFuture <= zero;
END IF;
cont <= "0000";
WHEN one => IF w = "00" THEN numbFuture <= one;
ELSIF w = "01" THEN numbFuture <= two;
ELSIF w = "10" THEN numbFuture <= three;
ELSIF w = "11" THEN numbFuture <= zero;
END IF;
cont <= "0001";
WHEN two => IF w = "00" THEN numbFuture <= two;
ELSIF w = "01" THEN numbFuture <= three;
ELSIF w = "10" THEN numbFuture <= four;
ELSIF w = "11" THEN numbFuture <= one;
END IF;
cont <= "0010";
WHEN three => IF w = "00" THEN numbFuture <= three;
ELSIF w = "01" THEN numbFuture <= four;
ELSIF w = "10" THEN numbFuture <= five;
ELSIF w = "11" THEN numbFuture <= two;
END IF;
cont <= "0011";
WHEN four => IF w = "00" THEN numbFuture <= four;
ELSIF w = "01" THEN numbFuture <= five;
ELSIF w = "10" THEN numbFuture <= six;
ELSIF w = "11" THEN numbFuture <= three;
END IF;
cont <= "0100";
WHEN five => IF w = "00" THEN numbFuture <= five;
ELSIF w = "01" THEN numbFuture <= six;
ELSIF w = "10" THEN numbFuture <= seven;
ELSIF w = "11" THEN numbFuture <= four;
END IF;
cont <= "0101";
WHEN six => IF w = "00" THEN numbFuture <= six;
ELSIF w = "01" THEN numbFuture <= seven;
ELSIF w = "10" THEN numbFuture <= eight;
ELSIF w = "11" THEN numbFuture <= five;
END IF;
cont <= "0110";
WHEN seven => IF w = "00" THEN numbFuture <= seven;
ELSIF w = "01" THEN numbFuture <= eight;
ELSIF w = "10" THEN numbFuture <= nine;
ELSIF w = "11" THEN numbFuture <= six;
END IF;
cont <= "0111";
WHEN eight => IF w = "00" THEN numbFuture <= eight;
ELSIF w = "01" THEN numbFuture <= nine;
ELSIF w = "10" THEN numbFuture <= nine;
ELSIF w = "11" THEN numbFuture <= eight;
END IF;
cont <= "1000";
WHEN nine => IF w = "00" THEN numbFuture <= nine;
ELSIF w = "01" THEN numbFuture <= nine;
ELSIF w = "10" THEN numbFuture <= nine;
ELSIF w = "11" THEN numbFuture <= eight;
END IF;
cont <= "1001";
END CASE;
END PROCESS;
PROCESS(clk)
BEGIN
IF (rising_edge(clk)) THEN
IF reset = '0' THEN numbCorr <= numbFuture ;
ELSE numbCorr <= zero;
END IF;
END IF;
END PROCESS;
END;
I think with this code is not possible that if the current state is "zero" the future state will be for example "seven" (from the FSM viewer seems that is possible). It is correct or I'm wrong?
this is the FSM produced by quartus (the numberState are in Italian because my original code was in italian to)

VHDL Counter 0 to 99

i have a problem with my code it supposed to count from 0 to 99 but the problem that i have is that the counter starts at "80" and the Left number only increments at 10 seconds so it repeats..
Something like this
Starts at: 80 81 82 83 84 04 05 06 07 08 09
My code is this:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned;
-- pin 86 selector de display 1
-- pin 87 selec2 display
-- Seg A pin 85, Seg B 84, Seg C 83, D 82, E 81, F 78, Seg g pin 77, H 76
entity ContadorExamen is
port(
CLK : in std_logic; -- se le asigna el pin 12
--clk1hz : out std_logic ;-- se le asigna el pin 51
datos : out std_logic_vector (6 downto 0);
unidades : out std_logic;
decenas: out std_logic
);
end entity;
architecture BH_Examen2Parcial of ContadorExamen is
signal freq1 : integer range 0 to 5000 := 0;
signal freqDec : integer range 0 to 24999999 := 0;
signal freq100 : integer range 0 to 249999999 := 0;
signal tmp1 : std_logic := '0';
signal tmp100 : std_logic := '0';
signal tmpDec : std_logic := '0';
signal counterUnidades : integer range 0 to 10 := 0;
signal counterDecenas : integer range 0 to 10 := 0;
signal segDecenas : std_logic_vector(6 downto 0);
signal segUnidades : std_logic_vector(6 downto 0);
begin
process(CLK) is
begin
if(CLK'event and CLK = '1') then
if(freq1 >= 5000) then
freq1 <= 0;
tmp1 <= not tmp1;
else
freq1 <= freq1 + 1;
tmp1 <= tmp1;
end if;
if(freq100 >= 249999999) then
freq100 <= 0;
tmp100 <= not tmp100;
else
freq100 <= freq100 + 1;
tmp100 <= tmp100;
end if;
if(freqDec >= 24999999) then
freqDec <= 0;
tmpDec <= not tmpDec;
else
freqDec <= freqDec + 1;
tmpDec <= tmpDec;
end if;
end if;
end process;
-- principio de cambios en el programa
process(tmp1) is
begin
if(tmp1 = '1') then
unidades <= '0';
decenas <= '1';
datos <= segDecenas;
else
datos <= SegUnidades;
decenas <= '0';
unidades <= '1';
end if;
end process;
ParaContarUnidades:process(tmp100) is
begin
if (tmp100 = '1') then
if(counterUnidades = 0) then
segUnidades <= "0000001";
elsif (counterUnidades = 1 ) then
segUnidades <= "1001111";
elsif (counterUnidades = 2 ) then
segUnidades <= "0010010";
elsif (counterUnidades = 3 ) then
segUnidades <= "0000110";
elsif (counterUnidades = 4 ) then
segUnidades <= "1001100";
elsif (counterUnidades = 5 ) then
segUnidades <= "0100100";
elsif (counterUnidades = 6 ) then
segUnidades <= "1100000";
elsif (counterUnidades = 7 ) then
segUnidades <= "0001111";
elsif (counterUnidades = 8 ) then
segUnidades <= "0000000";
elsif (counterUnidades = 9) then
segUnidades <= "0001100";
else
segUnidades <= "1111111";
end if;
if(counterUnidades < 9) then
counterUnidades <= counterUnidades + 1;
else
counterUnidades <= 0;
end if;
end if;
end process;
ParaContarDecenas:process(tmpDec) is
begin
if (tmpDec = '1') then
if(counterDecenas = 0) then
segDecenas <= "0000001";
elsif (counterDecenas = 1 ) then
segDecenas <= "1001111";
elsif (counterDecenas = 2 ) then
segDecenas <= "0010010";
elsif (counterDecenas = 3 ) then
segDecenas <= "0000110";
elsif (counterDecenas = 4 ) then
segDecenas <= "1001100";
elsif (counterDecenas = 5 ) then
segDecenas <= "0100100";
elsif (counterDecenas = 6 ) then
segDecenas <= "1100000";
elsif (counterDecenas = 7 ) then
segDecenas <= "0001111";
elsif (counterDecenas = 8 ) then
segDecenas <= "0000000";
elsif (counterDecenas = 9) then
segDecenas <= "0001100";
else
segDecenas <= "1111111";
end if;
if(counterDecenas < 9) then
counterDecenas <= counterDecenas + 1;
else
counterDecenas <= 0;
end if;
end if;
end process;
end architecture;
A couple issues that you will want to look into:
Note that counterDecenas and counterUnidades should be in the sensitivity list of the processes that use them because (as written) you want your segUnidades and segDecenas signals to update when tmpDec or tmp100 remain '1' but the counters change.
Moreover, you assign the counters to values based on themselves (such as counterDecenas <= counterDecenas + 1;) outside of a clocked process - this will produce a combinatorial loop. These need to be triggered only on clock edges.
Beyond that, it isn't clear what this entity is supposed to do. You say it is supposed to count from 0 to 99, but this clearly does more than the 1-liner that it would take to implement what you've described the desired functionality to be.

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";

Resources