Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

Not entering IF statement

Hello;

synopsys: Moore state machine, 2 processes executed concurrently. The first process determines current state/next state. The second process determines outputs.

problem: when the state machine is in the state "ADD_PILL_TOTAL" in the first process the outputs are not changing as per the "ADD_PILL_TOTAL" statement in the second process, It is not entering this statement at all. It enters all the other states and outputs properly in all other cases.

What I have tried: The commented out lines in the first process perform the function that I want and the state machine works the way I want it to when those lines are enabled and the corresponding lines in the second process are disabled.

PROCESS( StateMachineStart, StateMachineStop, StateMachinePillEqual, StateMachinePillDetected, StateMachineBottleDetected, Current_State)

BEGIN

Next_state <= Current_state;

-- BottleCounterEnable <= '0';

-- TotalPillCountStoreEnable <= '0';

if (Current_state = IDLE) then

if (StateMachineStart = '0') then

Next_state <= POSITION_BOTTLE;

else

next_state <= IDLE;

end if;

elsif (Current_state = POSITION_BOTTLE) then

if (StateMachineBottleDetected = '1') then

Next_state <= DISPENSE_PILL;

else

Next_state <= POSITION_BOTTLE;

end if;

elsif ((Current_state = DISPENSE_PILL)) then

if (StateMachinePillDetected = '0') then

Next_State <= PILL_DETECTED;

else

Next_State <= DISPENSE_PILL;

end if;

elsif ((Current_state = PILL_DETECTED)) then

if (StateMachinePillDetected = '1') then

Next_state <= ENABLE_PILL_COUNT;

else

Next_state <= PILL_DETECTED;

end if;

elsif (Current_state = ENABLE_PILL_COUNT) then

Next_state <= DISABLE_PILL_COUNT;

elsif (Current_state = DISABLE_PILL_COUNT) then

if (StateMachinePillEqual = '0') then

Next_state <= DISPENSE_PILL;

else

Next_state <= ADD_PILL_TOTAL;

end if;

elsif (Current_state = ADD_PILL_TOTAL) then

Next_state <= ADVANCE_NEW_BOTTLE;

-- BottleCounterEnable <= '1';

-- TotalPillCountStoreEnable <= '1';

elsif (Current_state = ADVANCE_NEW_BOTTLE)then

Next_state <= POSITION_BOTTLE;

end if;

END PROCESS ;

PROCESS (Current_state, Next_state)

BEGIN

BottleCounterEnable <= '0';

TotalPillCountStoreEnable <= '0';

PillCounterClear <= '0';

PillCountEnable <= '0';

OpenValve <= '0';

AdvanceConveyor <= '0';

if (Current_state = IDLE) then

PillCounterClear <= '1';

elsif (Current_state = POSITION_BOTTLE) then

AdvanceConveyor <= '1';

elsif (Current_state = (DISPENSE_PILL OR PILL_DETECTED OR PILL_NOT_DETECTED) ) then

OpenValve <= '1';

elsif (Current_state = ENABLE_PILL_COUNT) then

PillCountEnable <= '1';

OpenValve <= '1';

elsif (Current_state = DISABLE_PILL_COUNT) then

OpenValve <= '1';

elsif (Current_state = ADD_PILL_TOTAL) then

BottleCounterEnable <= '1';

TotalPillCountStoreEnable <= '1';

AdvanceConveyor <= '1';

elsif (Current_state = ADVANCE_NEW_BOTTLE) then

PillCounterClear <= '1';

AdvanceConveyor <= '1';

end if;

END PROCESS;

END;

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I presume, Current_state is assigned in a clocked process? How do you test FSM operation? Modelsim, hardware? Do you see ADD_PILL_TOTAL set for one clock cycle?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I forgot the 3rd process for the clock.

    PROCESS (Clock, StateMachineStop, Next_state)

    BEGIN

    IF (StateMachineStop = '0') THEN

    Current_state <= IDLE;

    ELSIF (rising_edge (Clock))

    Current_state <= Next_state;

    END IF;

    END PROCESS;

    the FSM is tested on a terasic DE2 board.

    ADD_PILL_TOTAL is set for one clock cycle as indicated by an external LED
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I wonder how this statement is evaluated, I fear not as an intersection, as apparently intended.

    elsif (Current_state = (DISPENSE_PILL OR PILL_DETECTED OR PILL_NOT_DETECTED) ) then

    The code would be much clearer with a case structure for the processes, I think,
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You are correct. It was that statement. I broke it into 2 more else if statements and It works fine now.

    I agree with you that the Case structure would be clearer. I'll give it a try implementing it with that method.

    Thank you
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I wonder how this statement is evaluated, I fear not as an intersection, as apparently intended.

    elsif (Current_state = (DISPENSE_PILL OR PILL_DETECTED OR PILL_NOT_DETECTED) ) then

    The code would be much clearer with a case structure for the processes, I think,

    --- Quote End ---

    This suggests the Current_state signal is a std_logic_vector. Any reason why you did this and not an enumerated type?

    doing an or like this will literally or the values together. So if the 3 things you put were 100, 010 and 001, it would be checking for current_state to be 111. You have to explicitly say:

    if current_state = X or Current_state = Y or current_state = Z then

    X =Y is a boolean return value in VHDL.