Search code examples
vhdlfsm

VHDL - FSM Control


I'm a beginner and I need a little help . My "current_s" is changing whenever rising edge of the clock detected. But, I want it to change only once when "Dot" or "Dash" is '1'.

I tried to create a signal like: Go_s<=Dot or Dash; And then tried to use its rising_edge to enable the process, but I've been told that it's not a good idea. But I can't think anything else.

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
-------------------------------------------------------------------------------
Entity Let5 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 Let5;
-------------------------------------------------------------------------------
Architecture Let5_a of Let5 is
-------------------------------------------------------------------------------
Type state is (Start, A, B, A_1, A_2, B_1, B_2);
Signal current_s: state;
-------------------------------------------------------------------------------
BEGIN
---------------------------------------------------------------------------------
PROCESS(Clk, Reset)
BEGIN
    IF(Reset='1')Then
    current_s<=Start;   
    ELSIF(Clk='1' and Clk'event)Then
    Case current_s is

        When Start =>
            IF(Dot='1')Then
                current_s<=A;               
            ELSIF(Dash='1')Then
                current_s<=B;               
            END IF;         

        When A =>       
            IF(Dot='1')Then
                current_s<=A_1;             
            ELSIF(Dash='1')Then
                current_s<=A_2;             
            END IF;     

        When B =>
            IF(Dot='1')Then
                current_s<=B_1;
            ELSIF(Dash='1')Then
                current_s<=B_2;
            END IF;

        When OTHERS => current_s <= Start;
    END Case;
    END IF;
END PROCESS;
-------------------------------------------------------------------------------
END Let5_a;

Simulation:

enter image description here


Solution

  • Add an conditional update of current_s inside the clocked process, using:

    ...
    elsif (Clk='1' and Clk'event) then
      if (Dot = '1') or (Dash = '1') then
        case current_s is
          ...
    

    Then current_s is updated only when the condition (Dot = '1') or (Dash = '1') is TRUE.

    It is correct what you have been told, that you should not make an additional signal Go_s checking for rising edge of this, since this is not the way to implement standard synchronous designs. Instead use a signal clock and make updates on rising edge, for example using rising_edge(Clk) instead of Clk='1' and Clk'event, and then make the updated conditional to whatever signal required. FPGAs and tools are made to implement this kind of design.