Search code examples
vhdlmodelsim

Strange spikes in the signal ModelSim VHDL


I'm working on a final project for school and this is my first time working with VHDL in Quartus and ModelSIM. It's supposed to be a control for an elevator that services three floors. I have these strange spikes in a few signals, and I can't seem to find their source.

The one problem I have is a spike in a signal that feeds to an up/down counter that shows the current floor. When it stops at a floor, it ends up counting one additional time and going either one floor too high or one floor too low, while the next floor display seems to show the same floor just fine until another floor is called. The next floor display comes from an FSM, while the current floor display is from an up/down counter.

It's a bit complex to post everything here, so I'm just going to post the waveform for now in case someone's come across this signal spike thing and it ends up being a minor error/easy fix.!

waveform

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity FSM_Elevador is
    port (Up_Down, Igual, Reset, Clock: in std_logic;
            Andar_Dif: out std_logic
            );
end FSM_Elevador;

architecture FSM_beh of FSM_Elevador is
    type Elev_States is (Start, Wait_State, Pulse_State);
    signal Current_State, Next_State: Elev_States;
    signal RST, CLK, Sig_Andar_Dif, Cont_Mesmo_Andar: std_logic;

begin

RST <= Reset;
CLK <= Clock;

process(RST, CLK)
begin
    if RST = '0' then
         Current_State <= Start;
    elsif CLK'event and  CLK = '1' then
         Current_State <= Next_State;
    end if;
end process;

process(Current_State, Igual)
begin
    case Current_State is
        when Start =>
            Next_State <= Wait_State;
        when Wait_State =>
            if Igual = '1' then
                Next_State <= Wait_State;
                Sig_Andar_Dif <= '0';
            else
                Next_State <= Pulse_State;
                Sig_Andar_Dif <= '1';
            end if;
        when Pulse_State =>
            if Igual = '1' then
                Sig_Andar_Dif <= '0';
                Next_State <= Wait_State;
            else
                Sig_Andar_Dif <= '0';
                Next_State <= Pulse_State;
            end if;
    end case;
end process;
Andar_Dif <= Sig_Andar_Dif;
end FSM_beh;

fru1tbat: I use the Elev_pulse to make the counter go up or down once, and yes it enters the counter as a clock. It was suggested by the professor.

Edit: sorry that was the wrong code earlier. Andar_Dif is what sends out the signal that ends up going to the component that has Elev_Pulse


Solution

  • Get rid of the reassignment of Clock and Reset to CLK and RST and just use the signals from the port directly. That is creating a delta cycle delay which is the cause of these kind of spikes. It looks like you have resets with different delays in the design which can also complicate matters. If the removal of the indirection doesn't clear things up you need to scrutinize the ordering of when events are generated on signals and when they are processed.

    The outputs from your state machine are unregistered which is also potentially involved. Consider reworking the FSM so that all outputs are registered. This is a better design practice in general as it ensures that you don't have unknown combinational delays affecting downstream logic.