Smoke apparatus 1011 detector in VHDL

I am writing a VHDL program for a Mealy machine that can detect the 1011 pattern like this:

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 a .do file to simulate 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 is incorrect. Can you help me solve this problem? Thank! enter image description here

+3


source to share


2 answers


You keep getting answers from people who seem to perceive the problem with result

.

The problem is that data

it is not in sync with clk

. You have transitions all over the place, the mealy conclusion does exactly what it should do.

This is a combinatorial output and should not be used like a watch. It can be used as a permission or entry for a register running on clk

.

Here's a test bench for those of us who don't have 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:

mealy_1011_tb.png (Interactive)

You don't want to see an extra drop on result

, do data

sync your watch. Your statemachine does exactly what it should.

And if there data

were synchronous clock cycles, you could shutter result

with clk

with not clk nand result

and create clock of result events.

+3


source


You just need to write your Mealy outputs to the if-then-else branch of your process.



NEXTSTATE: PROCESS(data, current_state)
BEGIN
    -- default assignments
    next_state <= state;       -- so your code won't create latches
    result     <= '0';         -- result is always 0, except of transition GOT101 to GOT1

    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
                result     <= '1';
                next_state <= GOT1;
            ELSE 
                next_state <= GOT10;
            END IF;
        WHEN OTHERS => NULL;
    END CASE;
END PROCESS NEXTSTATE;

      

0


source







All Articles