Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Code Check - Traffic Simulation

Altera_Forum
Honored Contributor II
1,613 Views

Hey guys,  

 

My program seems to be stuck in the first step of the State Machine and I cannot for the life of me figure out why, I suspect a problem with the counter? 

 

Any help is appreciated. 

 

counter: 

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.NUMERIC_STD.ALL; 

use IEEE.STD_LOGIC_ARITH.ALL; 

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

library UNISIM; 

use UNISIM.VComponents.all; 

 

 

entity Counter is 

Port ( reset : in STD_LOGIC; 

clear : in STD_LOGIC; 

clock : in STD_LOGIC; 

counto : out STD_LOGIC_vector (9 downto 0); -- count output 

finish : out STD_LOGIC 

finish2 : out STD_LOGIC 

); 

end Counter; 

 

 

architecture Behavioral of Counter is 

 

 

signal count_i: std_logic_vector (9 downto 0); -- 9 bit timer appropriate for 100Hz required speed 

signal cen: std_logic; -- count enable 

 

 

begin 

counto <= count_i; 

cen <= '1'; -- start count enable 

process (clear, reset, clock) begin -- begin process 

if (reset = '1') then -- if reset begin count to as if EW car has been there for a 'long time' 

count_i <= "1000000001"; 

elsif rising_edge (clock) then -- on rising edge of clock 

if (clear = '1') then 

cen <= '1'; -- if cleared begin counting 

count_i <= "0000000001"; 

elsif (cen = '1') then -- when count is enabled count up from 000000001 

count_i <= count_i + "000000001"; 

if (count_i >= "1000000001") then -- if minimum time is reached stop counting and wait for an input 

cen <= '0';  

finish <= '1'; 

if (count_i >= "0000100001") then 

cen <= '0';  

finish2 <= '1'; 

end if; 

end if; 

end if; 

end process; 

end architecture Behavioral; 

 

state machine 

 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.NUMERIC_STD.ALL; 

use IEEE.STD_LOGIC_ARITH.ALL; 

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

library UNISIM; 

use UNISIM.VComponents.all; 

 

 

-- Uncomment the following library declaration if using 

-- arithmetic functions with Signed or Unsigned values 

--use IEEE.NUMERIC_STD.ALL; 

 

 

-- Uncomment the following library declaration if instantiating 

-- any Xilinx primitives in this code. 

--library UNISIM; 

--use UNISIM.VComponents.all; 

 

 

entity StateMachine is 

Port ( 

clock : in STD_LOGIC; 

reset : in STD_LOGIC; 

carNS : in STD_LOGIC; 

carEW : in STD_LOGIC; 

finish : in STD_LOGIC; 

pedNS : in STD_LOGIC; 

pedEW : in STD_LOGIC; 

pedo : out STD_LOGIC; 

clearo : out STD_LOGIC; 

lightsEW : out STD_LOGIC_VECTOR (1 downto 0); -- controls EW lights 

lightsNS : out STD_LOGIC_VECTOR (1 downto 0); -- controls NS lights 

pedcount : in STD_LOGIC_vector (7 downto 0)); 

end StateMachine; 

 

 

architecture Behavioral of StateMachine is 

 

 

type StateType is (greenNS, amberNS, redNS, greenEW, amberEW, redEW); 

 

 

signal state, nextState: StateType;  

 

 

begin 

SynchronousProcess: -- execute all at once 

process (clock) begin -- only list clock, program auto fills required variables 

nextState <= greenEW; -- start at green EW light 

lightsEW <= "10"; -- car EW light green (10) 

lightsNS <= "00"; -- car NS lights red (01) 

case state is 

when greenEW => -- when car EW is green (10) 

lightsEW <= "10"; -- Good up to here 

if (finish = '1') then -- if count is above 1000000001 and a car is present on NS road then set EW light to amber 

if (carNS = '1') then 

nextState <= amberEW; 

clearo <= '1'; -- begin amber state, stop counting 

else -- else remain green for EW 

nextState <= greenEW; 

end if; 

end if; 

if (pedNS = '1') then -- if NS pedestrian button pressed 

nextState <= amberEW; 

clearo <= '1'; -- begin amber state, stop counting 

else 

nextState <= greenEW; -- else remain green for EW 

end if; 

when amberEW => -- when amber set lights to amber (01) 

lightsEW <="01"; 

if (finish2 = '1') then -- if count is above 0000100001 and a car is present on NS road then set EW light to red 

nextState <= redEW; 

clearo <= '1'; -- begin red state, stop counting 

end if; 

when redEW => -- when red set lights to red (00) 

lightsEW <="00"; 

if (finish = '1') then -- if count is above 1000000001 move to green state for NS road 

nextState <= greenNS; 

end if; 

when greenNS => -- when in green state set NS car lights to green (10) 

lightsNS <="10"; 

if (finish = '1') then -- if count is above 1000000001 and a car is present on EW road then set NS light to amber  

if (carEW = '1') then -- if car present on EW road,  

nextState <= amberNS; 

clearo <= '1'; -- begin amber state, stop counting 

else 

nextState <= greenNS; -- else stay green  

end if; 

end if; 

if (pedEW = '1') then -- if EW pedestrian button pressed 

nextState <= amberNS; -- begin amber state, stop counting 

clearo <= '1'; 

else 

nextState <= greenNS; -- else remain green for NS  

end if; 

when amberNS =>  

lightsNS <="11"; -- set NS lights to amber (11) 

if (finish2 = '1') then -- if count is above 0000100001 set NS lights to red  

nextState <= redNS;clearo <= '1'; 

end if; 

when redNS =>  

lightsNS <="00"; 

if (finish = '1') then -- if count is above 1000000001 set NS lights to red  

nextState <= greenEW; 

end if; 

end case; 

end process; 

 

 

process (reset,clock) begin -- begin process 

if (reset='1') then -- if reset go to state greenEW (first state) 

state <= greenEW; 

elsif rising_edge(clock) then -- else, if on a rising clock edge move to next state 

state <= nextState; 

clearo <='1'; -- stop counting 

end if; 

end process; 

 

 

end architecture Behavioral;
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
846 Views

Your counter seems to be ok, but what are the values of the input?

0 Kudos
Altera_Forum
Honored Contributor II
846 Views

Actually just realised that all the light settings are wrong.. From testing, should be as follows: 

11 is green (car and pedestrian) 

10 for green (car only) 

01 for amber 

00 for red 

 

Clock is at 100Hz 

 

Will update with nicer code and added comments in a second.
0 Kudos
Altera_Forum
Honored Contributor II
846 Views

Updated with commented code and fixed up some things.

0 Kudos
Altera_Forum
Honored Contributor II
846 Views

Ok, but what are the values of finish, carNS and pedNS? and what should happen if finish = '1' and carNs = '0'? or if both are 0 and pedNS is 0 as well? I think you have a few unspecified cases here.

0 Kudos
Altera_Forum
Honored Contributor II
846 Views

 

--- Quote Start ---  

Ok, but what are the values of finish, carNS and pedNS? and what should happen if finish = '1' and carNs = '0'? or if both are 0 and pedNS is 0 as well? I think you have a few unspecified cases here. 

--- Quote End ---  

 

 

The values of carNS etc should just be 0 and 1 - they are tied to inputs on a module, on a breadboard.  

 

Finish becomes 1 after account exceeds 1000000001.  

 

I hope this answers your question :P
0 Kudos
Altera_Forum
Honored Contributor II
846 Views

My question is: where is the testbench code? 

 

Second question: why have you put clock in the state machine sensitivity list, when it is clearly not a clocked process? and the comment is worrying, because it shows lack of understanding of VHDL: 

 

process (clock) begin -- only list clock, program auto fills required variables 

 

Quartus wont do any auto-filling for you. It will throw warnings about missing signals (note - not variables), but it ignores sensitivity lists, so you wont see a "problem". If you had a testbench, you would see that you would get many problems. 

 

thurdly - you state machine proces produces latches - these are not recommended. You need to assign all signals in ALL cases in an asynchronous process (it is not synchronous, it is asynchronous, despite your comments).
0 Kudos
Altera_Forum
Honored Contributor II
846 Views

Testbench code apparently was not needed. 

 

I did receive warnings but to me it read as though it was populating the sensitivity list with the inputs and outputs listed within the code. 

 

In then end I just decided to scrap the whole thing and start from scratch, end result was pretty close to what was required.  

 

Thank you for the input though, I have only done VHDL for about 2 weeks now and electronics is hardly my forte, more of a maths and programming man myself. 

 

 

--- Quote Start ---  

My question is: where is the testbench code? 

 

Second question: why have you put clock in the state machine sensitivity list, when it is clearly not a clocked process? and the comment is worrying, because it shows lack of understanding of VHDL: 

 

process (clock) begin -- only list clock, program auto fills required variables 

 

Quartus wont do any auto-filling for you. It will throw warnings about missing signals (note - not variables), but it ignores sensitivity lists, so you wont see a "problem". If you had a testbench, you would see that you would get many problems. 

 

thurdly - you state machine proces produces latches - these are not recommended. You need to assign all signals in ALL cases in an asynchronous process (it is not synchronous, it is asynchronous, despite your comments). 

--- Quote End ---  

0 Kudos
Reply