Search code examples
vhdlfsmflip-flop

FSM Mealy Machine Sequence Detector. How to use multiple flip flops?


Right now I am working on a small project in Vivado, a Mealy FSM. The program must detect a 6 bits sequence 001011, and output "1" when the sequence is detected.

The code concerning the sequence detection is doing just fine, but besides that, it must also use Three Flip Flops: JK, D, and T.

Any advice or suggestions on how to add them?

Thank you for your time.

This is the FSM code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;


entity sequence is
port(
    clk : in std_logic;
    reset : in std_logic;
    x: in std_logic;
    z : out std_logic;
    a : out std_logic;
    b : out std_logic;
    c : out std_logic;
    d : out std_logic;
    e : out std_logic;
    f : out std_logic);
end sequence;

architecture behavioral of sequence is


type state_type is (Q0, Q1, Q2, Q3, Q4, Q5);


signal state, next_state : state_type;

begin


state_register: process (clk, reset)
  begin
    if (reset = '1') then   --if reset is high, goto state Q0
       state <= Q0;
    elsif (clk'event and clk = '1') then    --if not, and rising 
       state <= next_state;                 --edge, go to next state
    end if;
end process;  


next_state_func: process (x, state)
begin 
  case state is 
      when Q0 =>
          if x = '0' then
             next_state <= Q1;
          else 
             next_state <= Q0;
          end if;
      when Q1 =>
           if x = '0' then
             next_state <= Q2;
           else
             next_state <= Q0;
           end if;
      when Q2 =>
           if x = '1' then
              next_state <= Q3;
           else 
              next_state <= Q2;
           end if;
      when Q3 =>
           if x ='0' then
              next_state <= Q4;
           else
              next_state <= Q0;
           end if;
      when Q4 =>
           if x = '1' then
              next_state <= Q5;
           else
              next_state <= Q2;
           end if;
      when Q5 =>
           if x = '1' then
              next_state <= Q0;
           else
              next_state <= Q1;                       
           end if;
      end case;
end process;

-- This process controls the output of the sequence detector.
-- Each state has it's own output along with 'z' which indicates
-- the entire sequence 001011 has been detected.
output_func:  process (x, state)
  begin
  case state is 
      when Q0 => z <= '0';
           a <= '1';
           b <= '0';
           c <= '0';
           d <= '0';
           e <= '0';
           f <= '0';
      when Q1 => z <= '0';
           a <= '0';
           b <= '1';
           c <= '0';
           d <= '0';
           e <= '0';
           f <= '0';
      when Q2 => z <= '0';
           a <= '0';
           b <= '0';
           c <= '1';
           d <= '0';
           e <= '0';
           f <= '0';
      when Q3 => z <= '0';
           a <= '0';
           b <= '0';
           c <= '0';
           d <= '1';
           e <= '0';
           f <= '0';
      when Q4 => z <= '0';
           a <= '0';
           b <= '0';
           c <= '0';
           d <= '0';
           e <= '1';
           f <= '0';
      when Q5 => z <= '1';
           a <= '0';
           b <= '0';
           c <= '0';
           d <= '0';
           e <= '0';
           f <= '1';
    end case;
  end process;

end behavioral;

[1]: https://i.sstatic.net/pVwxL.jpg - and here is the table that contains the State Diagram Table of the FSM.


Solution

  • Your code is wrong. Take a look at the output_func process; this is combinatorial, and just decodes the current state, without looking at x. The a to f outputs aren't necessary, and are just a 6-bit decode of the current state - why? The z output is set when the current state is Q5, which isn't what you want - the whole process is redundant. You need to set z in your main FSM, when the current state is Q5, and x is 1 - ie. on the next_state <= Q0 transition.

    On your actual question - you can't force selection of any particular F/F type with this code - the synthesiser will do whatever it wants, which means that it will implement the whole thing in D types, since JKs have been obsolete for the last 20 years. The same is probably true of T types. You need to start again, and pretend that you have a technology and a library with T, D, and JK. Write these yourself as separate entities, and re-write your code to instantiate these components, instead of allowing the synthesiser to infer them. Re-write your FSM to use JKs - the diagram you gave shows you how. In other words, derive the J and K inputs to each F/F. The z output can be a D-type. You should be able to fit in a T somewhere - I've left that as an exercise for you.