1

I'm having some trouble with this piece of code. It seems that state S0 is always active, even when it is not supposed to be. It appears that the output of this state is inverted(active when it is supposed to be disabled). Any ideas? Print of the simulation at the bottom. Thanks

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity ControlUnit is
     port(clk           : in  std_logic;
          reset         : in  std_logic;
          validTime     : in  std_logic;
          timeData      : in  std_logic_vector(3 downto 0);
          writeEnable   : out std_logic;
          writeAddress  : out std_logic_vector(3 downto 0);
          averageReady  : out std_logic);
end ControlUnit;

architecture Behavioral of ControlUnit is
    type TState is (S0, S1, S2, S3, S4, S5);
    signal PState, NState: TState;
begin

    sync_proc: process(clk, reset)
    begin
        if(reset = '1') then
            PState <= S0;
        elsif(rising_edge(clk)) then
            PState <= NState;
        end if;
    end process;

    comb_proc: process(PState, validTime, timeData)
    begin
        averageReady <= '0';
        writeEnable <= '0';
        case PState is
            when S0 =>
                if(validTime = '1') then
                    writeEnable <= '1';
                    NState <= S1;
                else
                    NState <= S0;
                end if;
            when S1 =>
                if(validTime = '1') then
                    writeEnable <= '1';
                    NState <= S2;
                else
                    NState <= S1;
                end if;
            when S2 =>
                if(validTime = '1') then
                    writeEnable <= '1';
                    NState <= S3;
                else
                    NState <= S2;
                end if;
            when S3 =>
                if(validTime = '1') then
                    writeEnable <= '1';
                    NState <= S4;
                else
                    NState <= S3;
                end if;
            when S4 =>
                if(validTime = '1') then
                    writeEnable <= '1';
                    NState <= S5;
                else
                    NState <= S4;
                end if;
            when S5 =>
                averageReady <= '1';
                NState <= S0;
            when others =>
                NState <= S0;
        end case;
    end process;

    with PState select
        writeAddress <= "0000" when S0,
                             "0001" When S1,
                             "0010" when S2,
                             "0011" when S3,
                             "0100" when S4,
                             "XXXX" when others;
end Behavioral;

Here's a print of the simulation:

(clickable)

Paebbels
  • 15,573
  • 13
  • 70
  • 139
Paulo Gil
  • 13
  • 3
  • 2
    This appears to be a one hot encoding (implying this is post synthesis simulation). The polarity of PState.S0 does appear to be inverted while the rest appear positive true. The synthesized hardware needs to keep the polarity straight but PState is not an output, does it simulate correctly? You haven't provided a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) allowing pre-synthesis simulation. *Any ideas?* is a bit broad for a question. Perhaps you could have constrained synthesis differently if you wanted to peer inside. –  May 20 '16 at 01:46

1 Answers1

0

Everything is ok with your code. Why do you suppose S0 state is always active? You can't say it from waveform, cause you don't know encoding scheme. On the other hand you writeAddress signal changes constantly meaning that your state machine changes its state.

ya_urock
  • 96
  • 1
  • 4
  • If you look at the S0 state and think of it inverted, wasn't it supposed to look like that, inverted? I mean, S0 state is the "default"... If none of the other states are active, then the only one active should have been S0, right? If you look at the gap at ~100ns, there is no active state... That sounds a bit odd to me – Paulo Gil May 22 '16 at 22:11
  • First of all. if you want to be exactly sure what state you are in, don't use that type enum definition. For state signal use simple std_logic_vector type and define constants for states by yourself. What we here is automatic enum type to std_logic_vector convertion which may lead to S0 state being encoded as "000000", what we see at waveform right after the reset signal. – ya_urock May 23 '16 at 05:22
  • Also I what to point out another mistake in your code - writeEnable is active during reset. That is because when reset is active you are in S0 state and if in this state validTime=1, then writeEn is also 1. This is not what you want I suppose. I would suggest to have one more state called RST_ST. Stay in it when reset signal is active, then move to S0 when it is not. So you writeEn signal will not be acitve during reset period – ya_urock May 23 '16 at 05:25