I write a VHDL program for Mealy machine that can detect the pattern 1011 as the following:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY mealy_detector_1011 IS
PORT(
rst_n : IN STD_LOGIC;
clk : IN STD_LOGIC;
data : IN STD_LOGIC;
result : OUT STD_LOGIC);
END ENTITY;
ARCHITECTURE beh OF mealy_detector_1011 IS
TYPE state IS (IDLE, GOT1, GOT10, GOT101);
SIGNAL current_state : state;
SIGNAL next_state : state;
BEGIN
REG: PROCESS(clk, rst_n)
BEGIN
IF rst_n = '0' THEN
current_state <= IDLE;
ELSIF rising_edge(clk) THEN
current_state <= next_state;
END IF;
END PROCESS REG;
NEXTSTATE: PROCESS(data, current_state)
BEGIN
CASE current_state IS
WHEN IDLE =>
IF data = '1' THEN
next_state <= GOT1;
ELSE next_state <= IDLE;
END IF;
WHEN GOT1 =>
IF data = '0' THEN
next_state <= GOT10;
ELSE next_state <= GOT1;
END IF;
WHEN GOT10 =>
IF data = '1' THEN
next_state <= GOT101;
ELSE next_state <= IDLE;
END IF;
WHEN GOT101 =>
IF data = '1' THEN
next_state <= GOT1;
ELSE
next_state <= GOT10;
END IF;
WHEN OTHERS => NULL;
END CASE;
END PROCESS NEXTSTATE;
result <= '1' WHEN (current_state = GOT101 and data = '1') ELSE '0';
END beh;
and file .do to simulating as the following
vcom mealy_detector_1011.vhd
vsim mealy_detector_1011
add wave -r /*
force -freeze /clk 1 0, 0 50 -r 100
force -freeze /rst_n 0 0, 1 10
force -freeze /data 0 0, 1 80, 0 180, 1 230, 0 330, 1 470, 0 530, 1 570, 0 620
run 800 ns
However, my simulation result isn't correct. Can you help me solve this problem? Thank you!
You keep getting answers from people who seem to perceive a problem with result
.
The issue is that data
is not synchronous to clk
. You have transitions all over the place, the mealy output is doing exactly what's it's supposed to do.
It's a combinatorial output and shouldn't be used as a clock. It can be used as an enable or an input to a register operating on clk
.
Here's a test bench for those of us without Modelsim:
library ieee;
use ieee.std_logic_1164.all;
entity mealy_1011_tb is
end entity;
architecture foo of mealy_1011_tb is
signal rst_n: std_logic := '0';
signal clk: std_logic := '1';
signal data: std_logic := '0';
signal result: std_logic;
begin
DUT:
entity work.mealy_detector_1011
port map (
rst_n => rst_n,
clk => clk,
data => data,
result => result
);
CLOCK:
process
begin
wait for 50 ns;
clk <= not clk;
if Now > 799 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
wait for 10 ns;
rst_n <= '1';
wait for 70 ns;
data <= '1'; -- 80 ns
wait for 100 ns;
data <= '0'; -- 180 ns
wait for 50 ns;
data <= '1'; -- 230 ns
wait for 100 ns;
data <= '0'; -- 330 ns
wait for 140 ns;
data <= '1'; -- 470 ns
wait for 60 ns;
data <= '0'; -- 530 ns
wait for 40 ns;
data <= '1'; -- 570 ns
wait for 50 ns;
data <= '0'; -- 620 ns
wait;
end process;
end architecture;
And it gives the same answer as your simulation:
You don't want to see the extra dip on result
, make data
clock synchronous. Your statemachine is doing exactly what's it's supposed to.
And if data
were clock synchronous you could gate result
with clk
using not clk nand result
and produce a result event clock.