VHDL FSM with a counter inside - vhdl

I am new here and here is my question:
I have a state machine with 3 states(s0,s1.s2) and input:(reset, clk, start) and output (done). My state machine works like this: on reset it comes to s0, and then if start = '1' goes to s2 and in this state I want it to stay there for 12 clock cycles (12 clock cycle delay) and then goes to s2 and done ='1' here and then back to s0.
My codes goes like this :
My code seems fine but my simulation result is not ok.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY fsm_count IS
port(clk : in std_logic;
reset : in std_logic;
start : in std_logic ;
don : out std_logic );
END ENTITY fsm_count;
--
ARCHITECTURE arc OF fsm_count IS
type statetype is (s0,s1,s2);
signal pr_state,nx_state : statetype;
signal s_counter : std_logic_vector (3 downto 0):=(others=>'0'); -- zero
begin
fsmcount: process(clk,reset,pr_state,start)
begin
if reset = '1'then pr_state <= s0;
elsif (clk'event and clk='1') then
case pr_state is
when s0 =>
if start ='1' then nx_state <=s1;
else nx_state <= s0;
end if;
when s1 =>
s_counter <= s_counter + '1';
if (s_counter = "1100") then
nx_state <= s2;
s_counter <=(others =>'0'); -- initializing the counter back to zero
else nx_state <=s1;
end if;
when s2 =>
nx_state<= s0;
end case;
end if;
end process fsmcount;
don <= '1' when (pr_state = s2) else '0';
END ARCHITECTURE arc;

I haven't synthetized it, but I think it should work. I you are not using VHDL2008, modify conditions so that bool types are returned:
ARCHITECTURE arc OF fsm_count IS
type statetype is (s0,s1,s2);
signal pr_state,nx_state: statetype;
signal s_counter: std_logic_vector (3 downto 0);
begin
process(clk) begin if rising_edge(clk) then
if rst then pr_state <= s0; else pr_state <= nx_state; end if;
end if; end process;
process(clk) begin if rising_edge(clk) then
if pr_state/=s1 then s_counter <= (others=>'0');
else s_counter <= s_counter+1; end if;
end if; end process;
process(all) begin
case pr_state is
when s0 =>
if start then nx_state <= s1;
else nx_state <= pr_state; end if;
when s1 =>
if s_counter?=12 then nx_state <= s2;
else nx_state <= pr_state; end if;
when s2 =>
nx_state<= s0;
end case;
end process;
don <= '1' when (pr_state = s2) else '0';
END arc;
EDIT
Alternatively, you can save s2 (i replaced pr_state with sta, nx_state with stn, and s_counter with cnt:
ARCHITECTURE arc OF fsm_count IS
signal idon: std_logic;
type t_st is (s0,s1);
signal sta, stn: t_st;
signal cnt: std_logic_vector (3 downto 0);
begin
process(clk) begin if rising_edge(clk) then
if rst then sta <= s0; else sta <= stn; end if;
end if; end process;
process(clk) begin if rising_edge(clk) then
if sta/=s1 then cnt <= (others=>'0');
else cnt <= cnt+1; end if;
end if; end process;
process(all) begin
case sta is
when s0 =>
if start then stn <= s1; else stn<=sta; end if;
when s1 =>
if idon then stn <= s0; else stn<=sta; end if;
end case;
end process;
idon <= cnt?=12;
don <= idon;
END arc;
Or, you can just use a flag:
ARCHITECTURE arc OF fsm_count IS
signal st, idon: std_logic;
signal cnt: std_logic_vector (3 downto 0);
begin
process(clk) begin if rising_edge(clk) then
if sta/=s1 then cnt <= (others=>'0');
else cnt <= cnt+1; end if;
end if; end process;
idon <= cnt?=12;
process(clk) begin if rising_edge(clk) then
if rst then st <= '0';
elsif not st and start then st <= '1';
elsif st and idon then st <= '0'; end if;
end if; end process;
don <= idon;
END arc;

Related

Bitsequence detector counter doesn't work (VHDL)

I build a 4 bit sequence detector with a 16-bit input.
I wanna now how often the sequence appears in the 16 bits.
For that I use this code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY seqdec IS
PORT ( X: IN std_logic_vector(15 DOWNTO 0);
CLK: IN std_logic;
RESET:IN std_logic;
LOAD: IN std_logic;
Y: OUT std_logic);
END seqdec;
ARCHITECTURE SEQ OF seqdec IS
TYPE statetype IS (s0, s1, s2, s3, s4);
SIGNAL state, next_state: statetype;
SIGNAL counter: std_logic_vector(3 DOWNTO 0) :="0000" ;
SIGNAL temp: std_logic_vector(15 DOWNTO 0);
SIGNAL so: std_logic;
BEGIN
STATE_AKT: PROCESS (CLK, RESET)
BEGIN
IF RESET = '1' THEN
state <= s0 ;
counter <= (OTHERS => '0') ;
ELSIF CLK = '1' AND CLK'event THEN
state <= next_state ;
END IF;
END PROCESS STATE_AKT;
PISO: PROCESS (CLK, LOAD, X)
BEGIN
IF (LOAD = '1') THEN
temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
ELSIF (CLK'event and CLK='1') THEN
so <= temp(15) ;
temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
temp(0) <= '0';
END IF;
END PROCESS PISO;
STATE_CAL: PROCESS (so,state)
BEGIN
CASE state IS
WHEN s0 => IF so = '0' THEN next_state <= s0 ;
ELSE next_state <= s1 ;
END IF;
WHEN s1 => IF so = '0' THEN next_state <= s1;
ELSE next_state <= s2 ;
END IF;
WHEN s2 => IF so = '0' THEN next_state <= s3 ;
ELSE next_state <= s2 ;
END IF;
WHEN s3 => IF so = '0' THEN next_state <= s0 ;
ELSE next_state <= s4 ;
END IF;
WHEN s4 => IF so = '0' THEN next_state <= s0;
ELSE next_state <= s2 ;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS STATE_CAL;
STATE_Y: PROCESS (state)
BEGIN
CASE state IS
WHEN s4 =>
Y <= '1';
counter <= counter + '1';
WHEN OTHERS => Y <= '0' ;
END CASE;
END PROCESS STATE_Y;
END SEQ;
But neither my counter reset nor my incrementation of counter is working.
The rest is working perfect and fine.
Has somebody a hint or an idea for me?
The programm is now working fine in ModelSim, but I struggle with getting it on the board.
I simulated it several times in ModelSim, with different parameters and it works fine, so the functional part is fine.
My code looks now this way:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY seqdec IS
PORT ( X: IN std_logic_vector(15 DOWNTO 0);
CLK: IN std_logic;
RESET: IN std_logic;
LOAD: IN std_logic;
DIGIT: OUT std_logic_vector(6 DOWNTO 0) := "1111110";
COUT: OUT std_logic_vector(2 DOWNTO 0);
Y: OUT std_logic);
END seqdec;
ARCHITECTURE SEQ OF seqdec IS
TYPE statetype IS (s0, s1, s2, s3, s4);
SIGNAL state: statetype;
SIGNAL next_state: statetype:=s0;
SIGNAL counter: std_logic_vector(2 DOWNTO 0) :="000" ;
SIGNAL temp: std_logic_vector(15 DOWNTO 0);
SIGNAL so: std_logic := 'U';
-------------------Aktualisierung des Zustandes--------------------------------
BEGIN
STATE_AKT: PROCESS (CLK, RESET)
BEGIN
IF RESET = '1' THEN
state <= s0;
ELSIF CLK = '1' AND CLK'event THEN
state <= next_state ;
END IF;
END PROCESS STATE_AKT;
---------------------Counter---------------------------------------------------
COUNT: PROCESS (state, RESET)
BEGIN
IF (RESET = '1') THEN
counter <= (OTHERS => '0');
ELSIF (state = s4) THEN
counter <= counter + '1';
COUT <= counter;
END IF;
END PROCESS COUNT;
-------------------PiSo für die Eingabe des zu Prüfenden Vektors---------------
PISO: PROCESS (CLK, LOAD, X)
BEGIN
IF (LOAD = '1') THEN
temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
ELSIF (CLK'event and CLK='1') THEN
so <= temp(15);
temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
temp(0) <= '0';
END IF;
END PROCESS PISO;
-------------------Zustandsabfrage und Berechnung------------------------------
STATE_CAL: PROCESS (so,state)
BEGIN
CASE state IS
WHEN s0 => IF so = '0' THEN next_state <= s0 ;
ELSIF (so = '1') THEN next_state <= s1 ;
END IF;
WHEN s1 => IF so = '0' THEN next_state <= s1;
ELSIF (so = '1') THEN next_state <= s2 ;
END IF;
WHEN s2 => IF so = '0' THEN next_state <= s3 ;
ELSIF (so = '1') THEN next_state <= s2 ;
END IF;
WHEN s3 => IF so = '0' THEN next_state <= s0 ;
ELSIF (so = '1') THEN next_state <= s4 ;
END IF;
WHEN s4 => IF so = '0' THEN next_state <= s0;
ELSIF (so = '1') THEN next_state <= s2 ;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS STATE_CAL;
-------------------Ausgang-----------------------------------------------------
STATE_Y: PROCESS (state)
BEGIN
CASE state IS
WHEN s4 =>
Y <= '1';
WHEN OTHERS => Y <= '0' ;
END CASE;
END PROCESS STATE_Y;
-------------------7 Segment---------------------------------------------------
SEVEN_SEG: PROCESS (counter, CLK)
BEGIN
IF (RESET = '1') THEN
DIGIT <= "1111110";
END IF;
CASE counter IS
WHEN "000" => DIGIT <= "1111110";
WHEN "001" => DIGIT <= "0110000";
WHEN "010" => DIGIT <= "1101101";
WHEN "011" => DIGIT <= "1111001";
WHEN "100" => DIGIT <= "0110011";
WHEN "101" => DIGIT <= "1011011";
WHEN OTHERS => NULL;
END CASE;
END PROCESS SEVEN_SEG;
END SEQ;
When i put it on the board the 7-segment will show a "3".
I would assume, as the functional part seems to be good,that it has to do somethink with the timings, but i can't find any solution to it. If some experience VHDL-programmer could give me a new hint that would be great.
Best regards
Adrian

VHDL Traffic Light

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Traffic_Light is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
input : in STD_LOGIC;
output : out STD_LOGIC_VECTOR(1 DOWNTO 0));
end Traffic_Light;
architecture Behavioral of Traffic_Light is
type state_type is (S0,S1,S2); --type of state machine.
signal present_state, next_state: state_type; --current and next state declaration.
begin
process
begin
wait until clk'event and clk = '0';
present_state <= next_state;
end process;
process (clk,reset)
begin
if (reset='1') then
current_state <= S0; --default state on reset.
end if;
end process;
process (present_state, input)
begin
case present_state is
when S0 => --when current state is s0
if(input = '0') then
output <= "10";
next_state <= S1;
else
output <= "00";
next_state <= S2;
end if;
when S1 => --when current state is s1
if(input = '0') then
output <= "01";
next_state <= S0;
else
output <= "00";
next_state <= S2;
end if;
when S2 => --when current state is s2
if(input = '0') then
output <= "01";
next_state <= S0;
else
output <= "11";
next_state <= S2;
end if;
end case;
end process;
end Behavioral;
I cant seem to get every state change to occur only at the falling edge of the clock.
The simulation does not show the various changes in the present state, it just shows S0 all the way through.
All the state changes have been entered correctly. It just requires the synchronous reset an state changes to occur at the falling edge.
First replace current_state with present_state. Then you can't drive present_state from two processes since it's not a resolved type. You have to do something like
process (clk,reset)
begin
if (reset='1') then
present_state <= S0; --default state on reset.
elsif clk'event and clk = '0' then
present_state <= next_state;
end if;
end process;

counting clock rising edges then produce a specific signal with FSM in VHDL

sorry for my weak english .
I want to write a VHDL code of simple Control unit or TPG controller that produce a signal like S2 , that motivated from FSM which count two rising edge of clock and then make the s2=1, so I want help to write a code wich count two rise edge then produce s2=1. then in third cycle make it zero.
here is my code that does not work :
LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
USE ieee.std_logic_unsigned.all ;
ENTITY TPG_CONTROL IS
PORT ( Clock : IN STD_LOGIC ;
TPG_CONTROL_En : IN STD_LOGIC ;
--reset : IN STD_LOGIC ;
ST2 : OUT STD_LOGIC ) ;
END TPG_CONTROL ;
ARCHITECTURE behav OF TPG_CONTROL IS
SIGNAL Count : std_logic_vector(1 DOWNTO 0) := "00" ;
TYPE state IS (S0, S1, S2);
SIGNAL Moore_state: state;
SIGNAL Clear: std_logic ;
begin
U_Moore0: PROCESS (clock, Clear, TPG_CONTROL_En, Count)
BEGIN
IF(Count = "11") THEN
Moore_state <= S0;
Clear <= '1';
ELSIF ( (rising_edge (clock)) AND TPG_CONTROL_En= '1') THEN
-- IF (Count = "11") THEN Clear <= '1' THEN
IF Clear = '1' THEN
Count <= "00" ;
ELSE
Count <= Count + 1 ;
-- END IF ;
-- END IF;
-- END IF;
-- END IF;
CASE Moore_state IS
WHEN S0 =>
IF Count = "01" THEN
Moore_state <= S1;
-- ELSE
-- Moore_state <= S0;
END IF;
WHEN S1 =>
IF Count = "10" THEN
Moore_state <= S2;
-- ELSE
-- Moore_state <= S1;
END IF;
WHEN S2 =>
IF Count = "11" THEN
Moore_state <= S0;
-- ELSE
-- Moore_state <= S1;
END IF;
END CASE;
END IF;
END IF;
--ST2 <= ‘1’ WHEN Moore_state = S2 ELSE ‘0’;
END PROCESS;
U_Moore1: PROCESS (clock, TPG_CONTROL_En)
BEGIN
IF ( (rising_edge (clock)) AND TPG_CONTROL_En= '1') THEN
IF ( Moore_state = S2 ) THEN ST2 <= '1' ;
ELSE ST2 <= '0' ;
END IF;
END IF;
END PROCESS;
END behav ;
Fixing the back ticks in you're comment:
Was:
--ST2 <= ‘1’ WHEN Moore_state = S2 ELSE ‘0’;
Is:
-- st2 <= '1' when moore_state = s2 else '0';
Your code analyzes and elaborates.
Writing a simple testbench:
library ieee;
use ieee.std_logic_1164.all;
entity tpg_control_tb is
end entity;
architecture foo of tpg_control_tb is
signal clk: std_logic := '0';
signal enab: std_logic := '1';
signal st2: std_logic;
begin
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 100 ns then
wait;
end if;
end process;
DUT:
entity work.tpg_control
port map (
clock => clk,
tpg_control_en => enab,
st2 => st2
);
end architecture;
with a constant tpg_control_en emonstrates the behavior to which you allude, that you aren't reaching S2.
If you comment out the asynchronous clear of moore_state by count:
u_moore0: process (clock, clear, tpg_control_en, count)
begin
if(count = "11") then
-- moore_state <= s0;
clear <= '1';
elsif ( (rising_edge (clock)) and tpg_control_en= '1') then
-- if (count = "11") then clear <= '1' then
if clear = '1' then
count <= "00" ;
else
count <= count + 1 ;
-- end if ;
-- end if;
-- end if;
-- end if;
case moore_state is
when s0 =>
if count = "01" then
moore_state <= s1;
-- else
-- moore_state <= s0;
end if;
when s1 =>
if count = "10" then
moore_state <= s2;
-- else
-- moore_state <= s1;
end if;
when s2 =>
if count = "11" then
moore_state <= s0;
-- else
-- moore_state <= s1;
end if;
end case;
end if;
end if;
-- st2 <= '1' when moore_state = s2 else '0';
end process;
You actually get there:
I'd suspect without knowing why you have an asynchronous clear that the process statement sensitivity list could be reduced to clock.
And because unsigned/std_logic_vector "+" rolls over you can simply the heck out of what you have:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity tpg_control is
port (
clock: in std_logic;
tpg_control_en: in std_logic;
--reset: in std_logic;
st2: out std_logic
);
end tpg_control;
architecture behav of tpg_control is
signal count : std_logic_vector(1 downto 0) := "00" ;
type state is (s0, s1, s2);
signal moore_state: state;
-- signal clear: std_logic;
begin
u_moore0:
process (clock)
begin
-- if(count = "11") then
-- moore_state <= s0;
-- clear <= '1';
-- elsif ...
if rising_edge(clock) and tpg_control_en = '1' then
-- if clear = '1' then
-- count <= "00" ;
-- else
count <= count + 1;
case moore_state is
when s0 =>
if count = "01" then
moore_state <= s1;
end if;
when s1 =>
if count = "10" then
moore_state <= s2;
end if;
when s2 =>
if count = "11" then
moore_state <= s0;
end if;
end case;
-- end if;
end if;
end process;
u_moore1:
process (clock)
begin
if rising_edge(clock) and tpg_control_en = '1' then
if moore_state = s2 then
st2 <= '1' ;
else st2 <= '0' ;
end if;
end if;
end process;
end behav ;
And this shows the state roll over:
Note that count and moore_state hold the same information in two different type formats. You don't actually need both. Generally synthesis tools would be capable of producing a working implementation from moore_state alone.

VHDL code for Tic tac toe game?

I have 18 output and 9 push switches to work with and one led as output which changing its states each time the push button is pressed to automate the chance of two players. my code is not working, pls help
my code is...expected behavour is that when momentarily in1 switch is high then play_to_play should toggle on each event of the inputs and according to play_to_play status and in1 high either ou11 or ou21 should go high i.e one player has played his chance and automatically at the next event it takes that it is player 2 chance
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TicTac 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;
reset : in STD_LOGIC;
p_to_play : out STD_Logic;
p1_win : out STD_LOGIC;
p2_win : out STD_LOGIC;
ou11 : out STD_LOGIC;
ou12 : out STD_LOGIC;
ou13 : out STD_LOGIC;
ou14 : out STD_LOGIC;
ou15 : out STD_LOGIC;
ou16 : out STD_LOGIC;
ou17 : out STD_LOGIC;
ou18 : out STD_LOGIC;
ou19 : out STD_LOGIC;
ou21 : out STD_LOGIC;
ou22 : out STD_LOGIC;
ou23 : out STD_LOGIC;
ou24 : out STD_LOGIC;
ou25 : out STD_LOGIC;
ou26 : out STD_LOGIC;
ou27 : out STD_LOGIC;
ou28 : out STD_LOGIC;
ou29 : out STD_LOGIC);
end TicTac;
architecture Behavioral of TicTac is
Signal temp1, temp2, temp3, temp4, temp5, temp6,temp7, temp8, temp9,p1_play :std_logic :='0';
signal o11,o12,o13,o14,o15,o16,o17,o18,o19,o21,o22,o23,o24,o25,o26,o27,o28,o29 :std_logic :='0';
signal p1win,p2win :std_logic :='0';
begin
process(in1,in2,in3,in4,in5,in6,in7,in8,in9,reset)
begin
if ((in1'event or in2'event or in3'event or in4'event or in5'event or in6'event or in7'event or in8'event or in9'event) and
(in1='1' or in2 ='1' or in3='1' or in4='1' or in5='1' or in6='1' or in7='1' or in8='1' or in9='1')) then
p1_play <= not(p1_play);
if(reset'event and reset= '1') then
temp1 <='0';
temp2 <='0';
temp3 <='0';
temp4 <='0';
temp5 <='0';
temp6 <='0';
temp7 <='0';
temp8 <='0';
temp9 <='0';
p1_play <= '0';
p1win <='0';
p2win <='0';
o11 <='0';
o12 <='0';
o13 <='0';
o14 <='0';
o15 <='0';
o16 <='0';
o17 <='0';
o18 <='0';
o19 <='0';
o21 <='0';
o22 <='0';
o23 <='0';
o24 <='0';
o25 <='0';
o26 <='0';
o27 <='0';
o28 <='0';
o29 <='0';
end if;
if(in1= '1') then
temp1 <='1';
end if;
if(in2= '1') then
temp2 <='1';
end if;
if(in3= '1') then
temp3 <='1';
end if;
if(in4= '1') then
temp1 <='1';
end if;
if(in5= '1') then
temp5 <='1';
end if;
if(in6= '1') then
temp6 <='1';
end if;
if(in7= '1') then
temp7 <='1';
end if;
if(in8= '1') then
temp8 <='1';
end if;
if(in9= '1') then
temp9 <='1';
end if;
if(p1_play='0' and temp1='1') then
o11 <= '1';
end if;
if(p1_play='0' and temp2='1') then
o12 <= '1';
end if;
if(p1_play='0' and temp3='1') then
o13 <= '1';
end if;
if(p1_play='0' and temp4='1') then
o14 <= '1';
end if;
if(p1_play='0' and temp5='1') then
o15 <= '1';
end if;
if(p1_play='0' and temp6='1') then
o16 <= '1';
end if;
if(p1_play='0' and temp7='1') then
o17 <= '1';
end if;
if(p1_play='0' and temp8='1') then
o18 <= '1';
end if;
if(p1_play='0' and temp9='1') then
o19 <= '1';
end if;
if(p1_play='1' and temp1='1') then
o21 <= '1';
end if;
if(p1_play='1' and temp2='1') then
o22 <= '1';
end if;
if(p1_play='1' and temp3='1') then
o23 <= '1';
end if;
if(p1_play='1' and temp4='1') then
o24 <= '1';
end if;
if(p1_play='1' and temp5='1') then
o25 <= '1';
end if;
if(p1_play='1' and temp6='1') then
o26 <= '1';
end if;
if(p1_play='1' and temp7='1') then
o27 <= '1';
end if;
if(p1_play='1' and temp8='1') then
o28 <= '1';
end if;
if(p1_play='1' and temp9='1') then
o29 <= '1';
end if;
if((o11='1' and o12='1' and o13='1') or (o14='1' and o15='1' and o16='1') or (o17='1' and o18='1' and o19='1')
or (o11='1' and o14='1' and o17='1') or (o12='1' and o15='1' and o18='1') or (o13='1' and o16='1' and o19='1')
or (o11='1' and o15='1' and o19='1') or (o13='1' and o15='1' and o17='1')) then
p1win <='1';
end if;
if((o21='1' and o22='1' and o23='1') or (o24='1' and o25='1' and o26='1') or (o27='1' and o28='1' and o29='1')
or (o21='1' and o24='1' and o27='1') or (o22='1' and o25='1' and o28='1') or (o23='1' and o26='1' and o29='1')
or (o21='1' and o25='1' and o29='1') or (o23='1' and o25='1' and o27='1')) then
p2win <='1';
end if;
end if;
end process;
ou11 <= o11;
ou12 <= o12;
ou13 <= o13;
ou14 <= o14;
ou15 <= o15;
ou16 <= o16;
ou17 <= o17;
ou18 <= o18;
ou19 <= o19;
ou21 <= o21;
ou22 <= o22;
ou23 <= o23;
ou24 <= o24;
ou25 <= o25;
ou26 <= o26;
ou27 <= o27;
ou28 <= o28;
ou29 <= o29;
p_to_play <= p1_play;
p1_win <= p1win;
p2_win <= p2win;
end Behavior
al;
Processes in VHDL are not the same as processes on a regular programming language. All signal assignments within a process actually occur at the time the process completes (actually a delta time later, which is basically a 0 time difference). Since you are trying to use the value of temp that you just assigned earlier in the process, but it hasn't actually been written yet, you are not triggering your if statement until the next time the process runs.
As an aside, I didn't notice any mechanism to prevent players from playing in spaces that they or their opponent already played.
EDIT: Also, what do you plan to do with this? If you want to put it on a real FPGA with real switches it likely won't work because of an electromechanical phenomenon called switch bouncing that makes each press of a switch seem like many to the hardware.
EDIT2: To fix this (still won't fix switch bouncing) you may want to scrap temp entirely (replacing it with the "in" signals) and put the entire contents of the process, except the reset stuff, inside your if statement that detects rising edges on the in signals.
EDIT3: Here is a VHDL model for a 4x4 tic-tac-toe board with your hardware setup expanded to the 16 squares of a 4x4 board. See if you can understand what is done and why, then adapt it to a 3x3 board.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TicTac is
Port (button : in std_logic_vector(16 downto 1);
reset : in std_logic;
p_to_play : out std_logic;
p1_win : out std_logic := '0';
p2_win : out std_logic := '0';
ou1 : out std_logic_vector(16 downto 1);
ou2 : out std_logic_vector(16 downto 1));
end TicTac;
architecture Behavioral of TicTac is
signal o1 : std_logic_vector(16 downto 1) := (others => '0');
signal o2 : std_logic_vector(16 downto 1) := (others => '0');
signal o : std_logic_vector(16 downto 1) := (others => '0');
signal p : std_logic;
signal win : std_logic;
signal win1 : std_logic;
signal win2 : std_logic;
begin
ou1 <= o1;
ou2 <= o2;
p_to_play <= p;
p1_win <= win1;
p2_win <= win2;
win <= win1 or win2;
gen_spots : for i in 1 to 16 generate --3 flip flops share a clock (button) for every space on the board
process(button(i), reset)
begin
if(reset = '1') then
o(i) <= '0';
o1(i) <= '0';
o2(i) <= '0';
elsif(button(i)'event and button(i)='1' and o(i)='0' and win='0') then
o(i) <= '1';
if (p = '0') then
o1(i) <= '1';
else
o2(i) <= '1';
end if;
end if;
end process;
end generate gen_spots;
process(o) --determines current player by xoring the o values together.
variable ot : std_logic;
begin
ot := '0';
for i in 1 to 16 loop
ot := ot xor o(i);
end loop;
p <= ot;
end process;
process(o1) --checks if player 1 wins
begin
win1 <= '0'; --only happens if none of the win1 <= '1' statements occur
for i in 0 to 3 loop
if (o1(1+i*4)='1' and o1(2+i*4)='1' and o1(3+i*4)='1' and o1(4+i*4)='1') then --rows
win1 <= '1';
end if;
if (o1(1+i)='1' and o1(5+i)='1' and o1(9+i)='1' and o1(13+i)='1') then --columns
win1 <= '1';
end if;
end loop;
if (o1(1)='1' and o1(6)='1' and o1(11)='1' and o1(16)='1') or (o1(4)='1' and o1(7)='1' and o1(10)='1' and o1(13)='1') then --diagonals
win1 <= '1';
end if;
end process;
process(o2) --checks if player 2 wins
begin
win2 <= '0'; --only happens if none of the win2 <= '1' statements occur
for i in 0 to 3 loop
if (o2(1+i*4)='1' and o2(2+i*4)='1' and o2(3+i*4)='1' and o2(4+i*4)='1') then --rows
win2 <= '1';
end if;
if (o2(1+i)='1' and o2(5+i)='1' and o2(9+i)='1' and o2(13+i)='1') then --columns
win2 <= '1';
end if;
end loop;
if (o2(1)='1' and o2(6)='1' and o2(11)='1' and o2(16)='1') or (o2(4)='1' and o2(7)='1' and o2(10)='1' and o2(13)='1') then --diagonals
win2 <= '1';
end if;
end process;
end Behavioral;
I haven't done exhaustive tests, but this compiles and works for a couple test cases.
Please remember to mark this as the correct answer if it solved your problem.
----------------------------------------------------------------------------------
----------------------------- TICTAC TOE GAME ------------------------------------
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity cs_main 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;
output1 : out STD_LOGIC_VECTOR (8 downto 0);
output2 : out STD_LOGIC_VECTOR (8 downto 0);
chance_real : out STD_LOGIC;
wing : out STD_LOGIC;
winr : out STD_LOGIC;
reset : in STD_LOGIC);
end cs_main;
architecture Behavioral of cs_main is
signal temp1,out1,out2,out11,out22 :std_logic_vector (8 downto 0):= "000000000";
signal chance : std_logic := '0';
signal wing1,winr1 : std_logic := '0';
begin
tictac :process(in1,in2,in3,in4,in5,in6,in7,in8,in9)
begin
if rising_edge (reset) then
out1 <= "000000000";
out2 <= "000000000";
chance <= '0';
wing1 <= '0';
winr1 <= '0';
else
if (wing1 = '0' and winr1 = '0') then
if rising_edge (in1) then
if (chance = '0') then
out1 <= "000000001";
elsif(chance = '1') then
out2 <= "000000001";
end if;
chance <= not chance ;
elsif rising_edge(in2) then
if (chance = '0') then
out1 <= "000000010";
elsif(chance = '1') then
out2 <= "000000010";
end if;
chance <= not chance ;
elsif rising_edge(in3) then
if (chance = '0') then
out1 <= "000000100";
elsif(chance = '1') then
out2 <= "000000100";
end if;
chance <= not chance ;
elsif rising_edge(in4) then
if (chance = '0') then
out1 <= "000001000";
elsif(chance = '1') then
out2 <= "000001000";
end if;
chance <= not chance ;
elsif rising_edge(in5) then
if (chance = '0') then
out1 <= "000010000";
elsif(chance = '1') then
out2 <= "000010000";
end if;
chance <= not chance ;
elsif rising_edge(in6) then
if (chance = '0') then
out1 <= "000100000";
elsif(chance = '1') then
out2 <= "000100000";
end if;
chance <= not chance ;
elsif rising_edge(in7) then
if (chance = '0') then
out1 <= "001000000";
elsif(chance = '1') then
out2 <= "001000000";
end if;
chance <= not chance ;
elsif rising_edge(in8) then
if (chance = '0') then
out1 <= "010000000";
elsif(chance = '1') then
out2 <= "010000000";
end if;
chance <= not chance ;
elsif rising_edge(in9) then
if (chance = '0') then
out1 <= "100000000";
elsif(chance = '1') then
out2 <= "100000000";
end if;
chance <= not chance ;
end if;
end if;
out11 <= out11 or out1;
out22 <= out22 or out2;
if(((out11 = "000000111" or out11 = "000111000" or out11 = "111000000" or
out11 = "001001001" or out11 = "010010010" or out11 = "100100100" or
out11 = "100010001" or out11 = "001010100" ) and chance ='0') or
((out22 = "000000111" or out22 = "000111000" or out22 = "111000000" or
out22 = "001001001" or out22 = "010010010" or out22 = "100100100" or
out22 = "100010001" or out22 = "001010100" ) and chance = '1')) then
if (chance = '0')then
wing1 <= '1';
winr1 <= '0';
elsif (chance = '1') then
wing1 <= '0';
winr1 <= '1';
end if;
else
wing1 <= '0';
winr1 <= '0';
end if;
end if;
end process tictac;
output1 <= out11 ;
output2 <= out22 ;
chance_real <= chance;
wing <= wing1;
winr <= winr1;
end Behavioral;
The code compiled without an error on my QUARTUS II version 15 software. i programmed it on my ALTERA DE2 FPGA BOARD but it does not display on the monitor. can anyone tell me what to do please
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TicTac is
Port (button : in std_logic_vector(16 downto 1);
reset : in std_logic;
p_to_play : out std_logic;
p1_win : out std_logic := '0';
p2_win : out std_logic := '0';
ou1 : out std_logic_vector(16 downto 1);
ou2 : out std_logic_vector(16 downto 1));
end TicTac;
architecture Behavioral of TicTac is
signal o1 : std_logic_vector(16 downto 1) := (others => '0');
signal o2 : std_logic_vector(16 downto 1) := (others => '0');
signal o : std_logic_vector(16 downto 1) := (others => '0');
signal p : std_logic;
signal win : std_logic;
signal win1 : std_logic;
signal win2 : std_logic;
begin
ou1 <= o1;
ou2 <= o2;
p_to_play <= p;
p1_win <= win1;
p2_win <= win2;
win <= win1 or win2;
gen_spots : for i in 1 to 16 generate --3 flip flops share a clock (button) for every space on the board
process(button(i), reset)
begin
if(reset = '1') then
o(i) <= '0';
o1(i) <= '0';
o2(i) <= '0';
elsif(button(i)'event and button(i)='1' and o(i)='0' and win='0') then
o(i) <= '1';
if (p = '0') then
o1(i) <= '1';
else
o2(i) <= '1';
end if;
end if;
end process;
end generate gen_spots;
process(o) --determines current player by xoring the o values together.
variable ot : std_logic;
begin
ot := '0';
for i in 1 to 16 loop
ot := ot xor o(i);
end loop;
p <= ot;
end process;
process(o1) --checks if player 1 wins
begin
win1 <= '0'; --only happens if none of the win1 <= '1' statements occur
for i in 0 to 3 loop
if (o1(1+i*4)='1' and o1(2+i*4)='1' and o1(3+i*4)='1' and o1(4+i*4)='1') then --rows
win1 <= '1';
end if;
if (o1(1+i)='1' and o1(5+i)='1' and o1(9+i)='1' and o1(13+i)='1') then --columns
win1 <= '1';
end if;
end loop;
if (o1(1)='1' and o1(6)='1' and o1(11)='1' and o1(16)='1') or (o1(4)='1' and o1(7)='1' and o1(10)='1' and o1(13)='1') then --diagonals
win1 <= '1';
end if;
end process;
process(o2) --checks if player 2 wins
begin
win2 <= '0'; --only happens if none of the win2 <= '1' statements occur
for i in 0 to 3 loop
if (o2(1+i*4)='1' and o2(2+i*4)='1' and o2(3+i*4)='1' and o2(4+i*4)='1') then --rows
win2 <= '1';
end if;
if (o2(1+i)='1' and o2(5+i)='1' and o2(9+i)='1' and o2(13+i)='1') then --columns
win2 <= '1';
end if;
end loop;
if (o2(1)='1' and o2(6)='1' and o2(11)='1' and o2(16)='1') or (o2(4)='1' and o2(7)='1' and o2(10)='1' and o2(13)='1') then --diagonals
win2 <= '1';
end if;
end process;
end Behavioral;

Why am I not getting output for following divide by 3 clock vhdl code?

There is no synthesis error in the following code, but still not getting the output when I simulate it. cout is staying logic 1 all the time. Please can anybody help me out to find out whats wrong?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity divide_by_3 is
port (
cout :out std_logic; -- Output clock
clk :in std_logic; -- Input clock
reset :in std_logic -- Input reset
);
end divide_by_3;
architecture Behavioral of divide_by_3 is
signal pos_cnt :std_logic_vector (1 downto 0);
signal neg_cnt :std_logic_vector (1 downto 0);
begin
process (clk, reset)
begin
if (reset = '1') then
pos_cnt <= (others=>'0');
elsif (rising_edge(clk)) then
if (pos_cnt = "10") then
pos_cnt <= pos_cnt + '1';
end if;
end if;
end process;
process (clk, reset) begin
if (reset = '1') then
neg_cnt <= (others=>'0');
elsif (falling_edge(clk)) then
if (neg_cnt = "10") then
neg_cnt <= neg_cnt + '1';
end if;
end if;
end process;
cout <= '1' when ((pos_cnt /= "10") and (neg_cnt /= "10")) else
'0';
end Behavioral;
Your counter will never count because you do:
if (neg_cnt = "10") then
neg_cnt <= neg_cnt + '1';
end if;
and
if (pos_cnt = "10") then
pos_cnt <= pos_cnt + '1';
end if;
but both, pos_cnt and neg_cnt are reset to "00". I guess you might want to do something similar like:
if (pos_cnt = "10") then
pos_cnt <= (others => '0');
else
pos_cnt <= pos_cnt + '1';
end if;

Resources