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

Rising Edge Problem in FSM

Altera_Forum
Honored Contributor II
1,511 Views

Hello, 

 

Since I'm a beginner, I need some advice. I was working with one input first, when I added my second input ,"Dash", it got complicated and I'm stuck. My states change depending on two inputs. You can think "current_s" as an output, I'll use it later. 

 

When my input follows this order "Dot-Dot" or "Dash-Dash" there is no problem. But, when it follows "Dash-Dot" or "Dot-Dash" then the "current_s" changes after second rising edge detected. I totally understand this because, if you look at the code, when my order changes, I mean when it follows "Dot-Dash" or "Dash-Dot", "next_s" changes too. Then it needs second rising edge to put this value into the "current_s". I'm out of ideas here, could you give me some ideas? I want the "current_s" to change immediately. 

 

I also need some ideas for "Pause" situation. I want it to continue from the last state. I couldn't figure something out. I tried to define a "last_s" state ,which shows me the last state obviously, and put it into the "next_s", when it's in "Pause" state. I don't remember why, but it didn't work either, I can tell you that. 

 

 

 

This is my code: 

library IEEE;use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; ------------------------------------------------------------------------------- Entity Let4 is Port( Clk: in std_logic; Reset: in std_logic; Dot: in std_logic; Dash: in std_logic; one_spc: in std_logic; three_spc: in std_logic); END Let4; ------------------------------------------------------------------------------- Architecture Let4_a of Let4 is ------------------------------------------------------------------------------- Type status is (Run, Pause, Stop, Zero); Type state is (Start, A, B, A_1, A_2, B_1, B_2); Signal current_s, next_s, last_let, last_word: state; Signal current_status: status; Signal Run_s: std_logic:='0'; -- IF(one_spc='0' and three_spc='0'). Signal Pause_s: std_logic:='0'; -- This goes '1' when one_spc is '1'. Signal Stop_s: std_logic:='0'; -- This goes '1' when three_spc is '1'. Signal Go_s: std_logic:='0'; -- Go_s<=Dash or Dot; (Line 98). ------------------------------------------------------------------------------- BEGIN ------------------------------------------------------------------------------- PROCESS(one_spc, three_spc, Reset) BEGIN -- This is to define how Run_s, Pause_s and Stop_s signals work. IF(Reset='1')Then current_status<=Zero; ELSIF(one_spc='0' and three_spc='0')Then current_status<=Run; Run_s<='1'; Pause_s<='0'; Stop_s<='0'; ELSIF(one_spc='1')Then current_status<=Pause; Pause_s<='1'; Stop_s<='0'; Run_s<='0'; ELSIF(three_spc<='1')Then current_status<=Stop; Pause_s<='0'; Stop_s<='1'; Run_s<='0'; END IF; END PROCESS; ------------------------------------------------------------------------------- PROCESS(Go_s, Reset) BEGIN IF(Reset='1')Then current_s<=start; ELSIF(Pause_s='1')Then current_s<=next_s; ELSIF(Go_s'Event and Go_s='1')Then -- If Dot or Dash is '1'. current_s<=next_s; END IF; END PROCESS; ------------------------------------------------------------------------------- PROCESS(Run_s, current_s, Dot, Dash) BEGIN IF(Pause_s='1')Then -- If one_spc is '1' I want to save the current data in last_let. last_let<=current_s; next_s<=???; -- Since it's a "Pause" state, I want it to continue from the last state, when Dot or Dash'1'. ELSIF(Stop_s='1')Then last_word<=current_s; -- If three_spc is '1' I want to save the current data in last_word. next_s<=???; -- Since it's a "Stop" state, I want it to go to the first state. ELSIF(Run_s='1')Then Case current_s is When Start => IF(Dot='1')Then next_s<=A; ELSIF (Dash='1')Then next_s<=B; END IF; When A => IF(Dot='1')Then next_s<=A_1; ELSIF(Dash='1')Then next_s<=A_2; END IF; When B => IF(Dot='1')Then next_s<=B_1; ELSIF(Dash='1')Then next_s<=B_2; END IF; When Others =>next_s<=Start; -- Doesn't matter for now. End Case; END IF; END PROCESS; ------------------------------------------------------------------------------- Go_s<=Dash or Dot; END Let4_a; 

 

 

 

Simulation picture: 

http://i41.tinypic.com/2dridnc.png  

 

 

 

 

Thank you. 

Best regards, 

Baris Yakut
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
752 Views

Before you delve into why its not behaving as you intended, I think we to discuss the major problems with your code. This entire design is asynchronous and will result in latches. There is no code that uses the input clock. I highly suggest you use the clock as doing this now will stop all sorts of problems that could occur later. You should also not use generated clocks internally (you have created a clock with go_s) as these can cause timing problems - you should use them as clock enables instead.

0 Kudos
Altera_Forum
Honored Contributor II
752 Views

First of all thank you for your suggestions. When I try to use the input clock as: 

 

PROCESS(Clk, Go_s, Reset) BEGIN IF(Reset='1')Then current_s<=start; ELSIF(Clk'event and Clk='1')Then current_s<=next_s; END IF; END PROCESS; 

 

Then I can't control it. Because states are changing when rising edge of the clock detected.
0 Kudos
Altera_Forum
Honored Contributor II
752 Views

Yes, thats the point. You can control it by using the input signals as enables to change the state. You will have major problems without using the clock.

0 Kudos
Altera_Forum
Honored Contributor II
752 Views

PROCESS(Clk, Go_s, Reset) BEGIN IF(Reset='1')Then current_s<=start; ELSIF(Clk'event and Clk='1')Then case currect_state is when start => if something_happened then current_state <= another_state; end if; when A => --etc END IF; END PROCESS;

0 Kudos
Reply