Reputation: 13
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
Reputation:
Analyzing, elaborating and simulating your design and testbench gives:
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:
And now we see the state machine is active.
Upvotes: 3