curirin
curirin

Reputation: 13

State machine in VHDL - unknow (unrecognized) output value

I am a beginner in VHDL coding and I have some problem with my simple state machine. I just want this machine to change the output value loc_RL when the state changes. When I am simulating, there is no value (like 'U') for loc_RL.

Here is my code:

library ieee;
use ieee.std_logic_1164.all;

entity RL is
    port (clk, reset, pon_RL, rtl_RL, ACDS_RL, LADS_RL, REN_RL, LLO_RL, MLA_RL, GTL_RL : in std_logic;
                                     loc_RL : out std_logic);
    end RL;

architecture behavioral of RL is

    type STATE_TYPE is (LOCS, REMS, LWLS, RWLS);
    signal state : STATE_TYPE;

begin
    process(clk, reset)
            begin
                if reset='1' then
                 state <= LOCS;
                elsif (rising_edge(clk)) then
                    case state is
                        when LOCS =>
                            if pon_RL = '1' then
                                state <= REMS;
                            else
                                state <= LOCS;
                            end if;
                        when REMS =>
                            if pon_RL = '1' then
                                state <= LWLS;
                            else
                                state <= REMS;
                            end if;
                        when LWLS =>
                            if pon_RL = '1' then
                                state <= RWLS;
                            else
                                state <= LWLS;
                            end if;
                        when RWLS =>
                            if pon_RL = '1' then
                                state <= LOCS;
                            else
                                state <= RWLS;
                            end if;
                    end case;
                end if;
    end process;


    process(state)
            begin
                case state is
                    when LOCS =>
                        loc_RL <= '1';
                    when REMS =>
                        loc_RL <= '0';
                    when LWLS =>
                        loc_RL <= '1';
                    when RWLS =>
                        loc_RL <= '0';
                end case;
    end process;

end behavioral;

testbench:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity RL_tb is
end RL_tb;

architecture testbench of RL_tb is
    component RL
    port (clk, reset, pon_RL, rtl_RL, ACDS_RL, LADS_RL, REN_RL, LLO_RL, MLA_RL, GTL_RL : in std_logic;
                                     loc_RL : out std_logic);
    end component;

    --wejscia
    signal tclk : std_logic;
    signal treset: std_logic;
    signal tpon_RL : std_logic;
    signal trtl_RL : std_logic;
    signal tACDS_RL : std_logic;
    signal tLADS_RL : std_logic;
    signal tREN_RL : std_logic;
    signal tLLO_RL : std_logic;
    signal tMLA_RL : std_logic;
    signal tGTL_RL : std_logic;

    --wyjscia
    signal loc_RL : std_logic;

    --definicja zegara
    constant clk_period : time := 40 ns;

begin
    --inicjalizacja UUT

    uut: RL port map (
                tclk,
                treset,
                tpon_RL,
                trtl_RL,
                tACDS_RL,
                tLADS_RL,
                tREN_RL,
                tLLO_RL,
                tMLA_RL,
                tGTL_RL
            );


    process
    begin
        tclk <= '0';
        wait for clk_period/2;
        tclk <= '1';
        wait for clk_period/2;
    end process;

    process
    begin
        treset <= '1';
        wait for 10 ns;
        treset <= '0';
        tpon_RL <= '1';


    end process;

end;

It is compiling correctly, I can proceed to the simulation. I am using NCLaunch from Cadence. Thanks in advance for help.

Upvotes: 1

Views: 88

Answers (1)

user1155120
user1155120

Reputation:

Analyzing, elaborating and simulating your design and testbench gives:

rl_tb.png

And looking at the testbench shows:

architecture testbench of RL_tb is
    component RL
        port (
            clk,
            reset,
            pon_RL,
            rtl_RL,
            ACDS_RL,
            LADS_RL,
            REN_RL,
            LLO_RL,
            MLA_RL,
            GTL_RL:     in  std_logic;
            loc_RL:     out std_logic
        );
    end component;

    --wejscia
    signal tclk:        std_logic;
    signal treset:      std_logic;
    signal tpon_RL:     std_logic;
    signal trtl_RL:     std_logic;
    signal tACDS_RL:    std_logic;
    signal tLADS_RL:    std_logic;
    signal tREN_RL:     std_logic;
    signal tLLO_RL:     std_logic;
    signal tMLA_RL:     std_logic;
    signal tGTL_RL:     std_logic;
    --wyjscia
    signal loc_RL:      std_logic;
    --definicja zegara
    constant clk_period:  time := 40 ns;

begin
    --inicjalizacja UUT
uut: 
    RL 
        port map (
            tclk,
            treset,
            tpon_RL,
            trtl_RL,
            tACDS_RL,
            tLADS_RL,
            tREN_RL,
            tLLO_RL,
            tMLA_RL,
            tGTL_RL
        );

    process
    begin
        tclk <= '0';
        wait for clk_period/2;
        tclk <= '1';
        wait for clk_period/2;
    end process;

    process
    begin
        treset <= '1';
        wait for 10 ns;
        treset <= '0';
        tpon_RL <= '1';
    end process;

end architecture;

No where is there an assignment to or initial value assigned to an input to the device under test other than clk, reset and tpon_RL.

Looking in the RL process we find that actual state branching out of LOCS depends on reset not being '1':

    process (clk, reset)
            begin
                if reset = '1' then
                 state <= LOCS;
                elsif (rising_edge(clk)) then
                    case state is
                        when LOCS =>
                            if pon_RL = '1' then
                                state <= REMS;
                            else
                                state <= LOCS;
                            end if;
                        when REMS =>

What's missing in your testbench stimulus is a release of the reset.

In the unlabeled process:

    process
    begin
        treset <= '1';
        wait for 10 ns;
        treset <= '0';
        tpon_RL <= '1';
    end process;

You're missing a final wait statement:

    process
    begin
        treset <= '1';
        wait for 10 ns;
        treset <= '0';
        tpon_RL <= '1';
        wait;            -- added
    end process;

Which prevents you from immediately assigning reset to a '1' again. Without suspension a process will loop, it's only suspending at the one wait statement, after setting reset to a '0' it's immediately setting it to a '1' before the process suspends, reset will only have a '1' value. No signal is updated while any process is active, there's only one projected output waveform value for any time, including the current simulation time. The assignment to a '1' overwrites the assignment to a '0'.

Fixing that gives:

rl_tb_fixed.png

And now we see the state machine is active.

Upvotes: 3

Related Questions