Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17268 Discussions

How to make delay between states in VHDL state machine?

Altera_Forum
Honored Contributor II
3,749 Views

I'm trying to make a specified time delay (in seconds) between states. As in: start at state0, wait 3 seconds, move to state1 wait 10, seconds, move to state 2. However there is an input, such that if the input =1 then the time must be reset. So far i though of this: 

 

Basically i made a counter to increment every second (from 24Mhz clock), and then used a binary signal to represent if the time is even or odd. I did this so that in each state i can test if a second has transpired and then increment the internal state clock. Once the internal clock reaches a value, I reset it and then transition to the next state. a to h represent LEDs, L and R are push down buttons on my DE1, FPGA. Ultimately I am just trying to learn how to make a state remain in itself until a certain amount of time has transpired. When I use this code, it doesnt function as i want it to, but im not sure why. 

 

library ieee; 

use ieee.std_logic_1164.all; 

 

 

entity prop is 

port ( L, R, CLK : in std_logic; 

a, b, c, d, e, f, g, h : out std_logic ); 

end prop; 

 

 

architecture behaviour of prop is 

type state is (stopr, runl, stopl); 

signal current_s, next_s : state; 

signal counter : integer range 0 to 24000001 := 0; 

signal sys_clock : integer range 0 to 36288000 := 0; 

signal sub_clock : integer range 0 to 36288000 := 0; 

signal clkevent : std_logic := '0'; 

signal check : std_logic := '0'; 

begin 

 

 

state_register: process (CLK) 

begin 

if (rising_edge(CLK)) then  

counter <= counter + 1; 

if (counter = 24000000) then 

counter <= 0; 

sys_clock <= sys_clock + 1; 

end if; 

if (sys_clock mod 2 = 0) then 

clkevent <= '0'; 

else clkevent <= '1'; 

end if;  

current_s <= next_s; 

end if;  

 

end process state_register; 

 

 

 

 

next_state_logic: process (current_s, L, R) 

begin 

case current_s is 

when stopr => 

if (L = '1' OR R = '1') then 

next_s <= stopr; 

sub_clock <= 0; 

elsif (check = NOT(clkevent))then 

sub_clock <= sub_clock + 1; 

check <= clkevent; 

if (sub_clock = 3) then 

next_s <= runl; 

sub_clock <= 0;  

else  

next_s <= stopr; 

end if; 

else  

next_s <= stopr; 

end if; 

 

when runl =>  

if (L = '1' OR R = '1') then 

next_s <= stopr; 

sub_clock <= 0; 

elsif (check = NOT(clkevent))then 

sub_clock <= sub_clock + 1; 

check <= clkevent; 

if (sub_clock = 11) then 

sub_clock <= 0; 

next_s <= stopl; 

else  

next_s <= runl;  

end if; 

else  

next_s <= runl; 

end if; 

 

when stopl => 

if (R = '1') then 

next_s <= stopr; 

else  

next_s <= stopl;  

end if;  

 

when others => 

next_s <= stopr; 

end case; 

end process next_state_logic; 

 

 

output_logic: process (current_s) 

begin 

case current_s is 

when stopr => 

a <= '1'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

when stopl => 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '1'; 

when runl => 

if (sub_clock = 3) then 

a <= '0'; b <= '1'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; end if; 

if (sub_clock = 4) then 

a <= '0'; b <= '0'; c <= '1'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0';end if; 

if (sub_clock = 5) then  

a <= '0'; b <= '0'; c <= '0'; d <= '1'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0';end if; 

if (sub_clock = 6) then  

 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '1'; f <= '0'; g <= '0'; h <= '0';end if; 

if (sub_clock = 7) then  

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '1'; g <= '0'; h <= '0';end if; 

if (sub_clock = 8) then  

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '1'; h <= '0';end if; 

if (sub_clock = 9) then  

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '1'; 

end if; 

when others => 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

end case; 

end process output_logic; 

 

 

 

 

end behaviour;
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
2,546 Views

I suggest using a clock for all of your code. Im guessing you're getting warnings about latches? 

 

There are several problems with the code. 

Your sub_clock counter wont work as you think it will because its not in a synchronous process. With your process, it will try and add 1 in a logic loop.  

You are missing signals in the sensitivity list for the next state logic. Without the correct list, simulation will not behave like the real hardware (you're missing sub_clock, check, clkevent
0 Kudos
Altera_Forum
Honored Contributor II
2,546 Views

Okay, so I tried to Fix it by taking a slightly different approach, but it still doeesnt behave the way it should. I'm still very new to VHDL so theres probably some fundamental concept that I'm not understanding.  

 

----------------- CLOCK_start ------------------- 

 

library ieee; 

 

use ieee.std_logic_1164.all; 

 

entity Sys_clk is 

port  

( CLK : in std_logic; 

Freq : out std_logic 

); 

end Sys_clk; 

 

architecture Clock_behave of Sys_clk is 

signal counter : integer range 0 to 24000001 := 0; 

signal osc : std_logic := '0'; 

begin 

S_reg: process(CLK) 

begin 

if (rising_edge(CLK))then 

counter <= counter + 1; 

if (counter = 3000000)then 

if (osc = '0') then  

osc <= '1'; 

else  

osc <= '0'; 

end if; 

counter <= 0; 

end if; 

Freq <= osc; 

end if; 

end process s_reg; 

 

end Clock_behave; 

 

----------------- CLOCK_end ------------------- 

 

-------------- Ping Pong_start ------------------- 

 

library ieee; 

 

use ieee.std_logic_1164.all; 

 

entity Ping_Pong is 

port( 

Start, Lb, Rb, CLK : in std_logic; 

a,b,c,d,e,f,g,h : out std_logic 

); 

 

end Ping_Pong; 

 

architecture Pong_Behave of Ping_Pong is 

type state is (wait_s, stopr_s, stopl_s, runr_s, runl_s); 

signal pres_s, next_s : state; 

signal count : integer range 0 to 10000000 :=0; 

begin 

 

State_Logic: process(CLK, start, Lb, Rb ) 

begin 

if(start = '0') then 

pres_s <= wait_s; 

elsif(rising_edge(CLK)) then 

count <= count +1; 

case pres_s is 

when wait_s =>  

next_s <= stopr_s;  

count <= 0; 

when stopr_s =>  

if (Lb = '1' OR Rb = '1')then 

next_s <= stopr_s; 

count <= 0; 

else  

if (count = 12)then 

next_s <= runl_s; 

count <= 0; 

else  

next_s <= stopr_s; 

end if;  

end if;  

when runl_s => 

if (Lb = '1' OR Rb = '1')then 

next_s <= stopr_s; 

count <= 0; 

else  

if (count = 72)then 

next_s <= stopl_s; 

count <= 0; 

else  

next_s <= runl_s; 

end if;  

end if;  

when stopl_s => 

if (Rb = '1')then 

next_s <= stopr_s; 

count <= 0; 

elsif (Lb = '1')then  

next_s <= stopl_s; 

count <= 0; 

else  

if (count = 12)then 

next_s <= runr_s; 

count <= 0; 

else  

next_s <= stopl_s; 

end if;  

end if;  

when runr_s => 

if (Lb = '1' OR Rb = '1')then 

next_s <= stopr_s; 

count <= 0; 

else  

if (count = 72)then 

next_s <= stopr_s; 

count <= 0; 

else  

next_s <= runr_s; 

end if;  

end if;  

when others => 

next_s <= wait_s; 

end case; 

pres_s <= next_s; 

end if;--start = 0 

end process State_Logic; 

 

output_logic: process (pres_s,count) 

begin 

case pres_s is 

when wait_s => 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

when stopr_s =>  

a <= '1'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

when runl_s => 

if (count = 0) then 

a <= '0'; b <= '1'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

end if; 

if (count = 12) then 

a <= '0'; b <= '0'; c <= '1'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

end if; 

if (count = 24) then 

a <= '0'; b <= '0'; c <= '0'; d <= '1'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

end if; 

if (count = 36) then 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '1'; f <= '0'; g <= '0'; h <= '0'; 

end if; 

if (count = 48) then 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '1'; g <= '0'; h <= '0'; 

end if; 

if (count = 60) then 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '1'; h <= '0'; 

end if; 

if (count = 72) then 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '1'; 

end if; 

 

when stopl_s => 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '1'; 

when runr_s => 

if (count = 0) then 

h <= '0'; g <= '1'; f <= '0'; e <= '0'; 

d <= '0'; c <= '0'; b <= '0'; a <= '0'; 

end if; 

if (count = 12) then 

h <= '0'; g <= '0'; f <= '1'; e <= '0'; 

d <= '0'; c <= '0'; b <= '0'; a <= '0'; 

end if; 

if (count = 24) then 

h <= '0'; g <= '0'; f <= '0'; e <= '1'; 

d <= '0'; c <= '0'; b <= '0'; a <= '0'; 

end if; 

if (count = 36) then 

h <= '0'; g <= '0'; f <= '0'; e <= '0'; 

d <= '1'; c <= '0'; b <= '0'; a <= '0'; 

end if; 

if (count = 48) then 

h <= '0'; g <= '0'; f <= '0'; e <= '0'; 

d <= '0'; c <= '1'; b <= '0'; a <= '0'; 

end if; 

if (count = 60) then 

h <= '0'; g <= '0'; f <= '0'; e <= '0'; 

d <= '0'; c <= '0'; b <= '1'; a <= '0'; 

end if; 

if (count = 72) then 

h <= '0'; g <= '0'; f <= '0'; e <= '0'; 

d <= '0'; c <= '0'; b <= '0'; a <= '1'; 

end if; 

when others => 

a <= '0'; b <= '0'; c <= '0'; d <= '0'; 

e <= '0'; f <= '0'; g <= '0'; h <= '0'; 

end case; 

end process output_logic; 

-- 

 

end Pong_Behave; 

-------------- Ping Pong_end -------------------
0 Kudos
Altera_Forum
Honored Contributor II
2,546 Views

Could someone please help me understand whats wrong?

0 Kudos
Reply