Altera_Forum
Honored Contributor
12 years agoHow to make delay between states in VHDL state machine?
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;