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

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.stack.imgur.com/pVwxL.jpg - and here is the table that contains the State Diagram Table of the FSM.

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.

Related

VHDL Error simulating a Mealy Finite State Machine sequence detector

I'm writing code for a Mealy FSM sequence detector with detection of input sequences 01110010 and 00100111. Overlapping is allowed.
I can compile both the code and had set the top level to the testbench but when I simulate I'm not getting any waveform.
This is the circuit code
library ieee;
use ieee.std_logic_1164.ALL;
entity SequenceDetector_8bit is
port( X : in std_logic;
RST: in std_logic;
CLK: in std_logic;
Z : out std_logic);
end SequenceDetector_8bit;
architecture Behavior of SequenceDetector_8bit is
type state is (S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13);
signal PresentState, NextState : state;
signal Z0: std_logic;
begin
clk_process:process(CLK,RST)
begin
if RST = '1' then
PresentState <= S0;
elsif rising_edge(CLK) then
PresentState <= NextState;
end if;
end process clk_process;
state_process: process(PresentState, X) -- process executed if state variables.
begin
case PresentState is -- check present state,
when S0 => -- when present state is state-S0
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S1; -- and advance to state-S1
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S0; -- and stay back at state-S0
end if;
when S1 => -- when present state is state-S1
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S8; -- and advance to state-S8
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S2; -- and advance to state-S2
end if;
when S2 => -- when present state is state-S2
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S0; -- and advance to state-S0
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S3; -- and advance to state-S3
end if;
when S3 => -- when present state is state-S3
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S0; -- and advance to state-S0
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S4; -- and advance to state-S4
end if;
when S4 => -- when present state is state-S0
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S5; -- and advance to state-S5
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S0; -- and advance to state-S0
end if;
when S5 => -- when present state is state-S5
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S6; -- and advance to state-S6
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S2; -- and advance to state-S2
end if;
when S6 => -- when present state is state-S6
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S8; -- and advance to state-S8
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S7; -- and advance to state-S7
end if;
when S7 => -- when present state is state-S7
if (X='0') then -- and when input X = 0,
Z0 <= '1'; -- produce output 1
NextState <= S10; -- and advance to state-S10
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S3; -- and advance to state-S3
end if;
when S8 => -- when present state is state-S8
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S8; -- and stay back at state-S8
else -- when input X = 1,
Z0 <= '0'; -- produce output 1
NextState <= S9; -- and advance to state-S9
end if;
when S9 => -- when present state is state-S9
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S10; -- and advance to state-S10
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S3; -- and advance to state-S3
end if;
when S10 => -- when present state is state-S10
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S11; -- and advance to state-S11
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S12; -- and advance to state-S12
end if;
when S11 => -- when present state is state-S11
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S8; -- and advance to state-S8
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S12; -- and advance to state-S12
end if;
when S12 => -- when present state is state-S12
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S8; -- and advance to state-S8
else -- when input X = 1,
Z0 <= '0'; -- produce output 0
NextState <= S13; -- and advance to state-S13
end if;
when S13 => -- when present state is state-S13
if (X='0') then -- and when input X = 0,
Z0 <= '0'; -- produce output 0
NextState <= S1; -- and advance to state-S1
else -- when input X = 1,
Z0 <= '1'; -- produce output 1
NextState <= S4; -- and advance to state-S4
end if;
end case;
end process state_process;
output_latch: process(CLK)
begin
if rising_edge(CLK) then
Z <= Z0;
end if;
end process output_latch;
end Behavior;
And this is the Test Bench code I had written
library ieee;
use ieee.std_logic_1164.ALL;
entity SequenceDetector_8bit_tb is
end SequenceDetector_8bit_tb;
architecture Behavior of SequenceDetector_8bit_tb is
--Input Signal Declaration and initialization
signal CLK : std_logic := '0';
signal X : std_logic := '0';
signal RST : std_logic := '0';
--Output Signal Declaration and initialization
signal Z : std_logic;
constant clk_period: time :=2 ms;
begin
-- instantiate the Unit Under Test (UUT)
mut: entity work.SequenceDetector_8bit
-- using position association
port map(CLK => CLK,
X => X,
RST => RST,
Z => Z);
clk_process: process
begin
CLK <= '0';
wait for clk_period/2;
CLK <= '1';
wait for clk_period/2;
end process clk_process;
stimulus_process: process
begin
-- test sequence
X <= '0';
wait for clk_period;
X <= '1';
wait for clk_period;
X <= '1';
wait for clk_period;
X <= '1';
wait for clk_period;
X <= '0';
wait for clk_period;
X <= '0';
wait for clk_period;
X <= '1';
wait for clk_period;
X <= '0';
wait for clk_period;
wait;
end process stimulus_process;
end Behavior;

Modelsim VHDL testbench

This is my VHDL code in Modelsim. The problem is that output is uninitialized, as you can see in the image. Please tell me what's the problem with my code.
library ieee;
use ieee.std_logic_1164.All;
use IEEE.NUMERIC_STD.ALL;
entity circu_it is
port (A : in std_logic;
B : in std_logic;
C : in std_logic;
D : in std_logic;
Z : out std_logic );
end circu_it;
architecture Behavioral of circu_it
is
Signal E ,F ,M ,N , L: std_logic;
begin
M <= (A and B and C) after 5ns;
E <= (M or D) after 5ns;
N <= (B nor C) after 5ns;
F <= (N nand A) after 5ns;
L <= not F after 2ns;
Z <= L xor E after 5ns;
end Behavioral;
The testbench of code is the following ......
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
entity delay_test is
end delay_test;
architecture stimulus of delay_test is
component delay
port (
A : in std_logic;
B : in std_logic;
C : in std_logic;
D : in std_logic;
Z : out std_logic);
end component;
signal A: std_logic ;
signal B: std_logic ;
signal C: std_logic ;
signal D: std_logic ;
signal Z: std_logic ;
begin
DUT: delay port map ( A => A, B => B, C => C, D => D, Z => Z);
STIMULUS1: process
constant PERIOD: time := 100 ns;
begin
A <= '0';
B <= '0';
C <= '0';
D <= '0';
wait for period;
A <= '0';
B <= '0';
C <= '0';
D <= '1';
wait for period;
A <= '0';
B <= '0';
C <= '1';
D <= '0';
wait for period;
A <= '0';
B <= '0';
C <= '1';
D <= '1';
wait for period;
A <= '0';
B <= '1';
C <= '0';
D <= '0';
wait for period;
A <= '0';
B <= '1';
C <= '0';
D <= '1';
wait for period;
A <= '0';
B <= '1';
C <= '1';
D <= '0';
wait for period;
A <= '0';
B <= '1';
C <= '1';
D <= '1';
wait for period;
A <= '1';
B <= '0';
C <= '0';
D <= '0';
wait for period;
A <= '1';
B <= '0';
C <= '0';
D <= '1';
wait for period;
A <= '1';
B <= '0';
C <= '1';
D <= '0';
wait for period;
A <= '1';
B <= '0';
C <= '1';
D <= '1';
wait for period;
A <= '1';
B <= '1';
C <= '0';
D <= '0';
wait for period;
A <= '1';
B <= '1';
C <= '0';
D <= '1';
wait for period;
A <= '1';
B <= '1';
C <= '1';
D <= '0';
wait for period;
A <= '1';
B <= '1';
C <= '1';
D <= '1';
wait;
end process;
end stimulus;
Your design entity is circu_it. You have instantiated a component called delay. You either need to
write a configuration to bind the two together
change the name of either the component or the entity so that they are the same (so that default binding occurs).

Finite state machine VHDL reset

I am new to VHDL and I have a question about the implementation of a FSM.
I would like the behaviour shown in the picture (where I implemented the same FSM with AHDL). When I implement it in VHDL I have a different behaviour of the reset : if it detects reset=1 and at the same time there is a rising edge the FSM does not go on but it keeps on putting PS at S0.
I know the problem is that if... elsif (it detects right the 1st condition and does not enter in the 2nd I suppose).
I have tried in many different ways but still is not working and the output stays at 00 also after the 1st rising edge.
Waveforms of AHDL implementation:
Waveforms of VHDL implementation:
LIBRARY ieee; -- Bibliotheksvereinbarung
USE ieee.std_logic_1164.all;
ENTITY sumconvol IS -- Schaltungssymbol
PORT
(
x : IN STD_LOGIC; --input of 1st FF
clk : IN STD_LOGIC; --clock of all the 3 FFs
clrn : IN STD_LOGIC;
y : OUT STD_LOGIC_VECTOR (1 downto 0) --vector of output data
);
END sumconvol;
ARCHITECTURE a OF sumconvol IS -- Creation of architecture
--SIGNAL output_tmp : STD_LOGIC_VECTOR (1 downto 0); -- temporary variables (e.g. input/output between FFs)7
TYPE state_type IS (S0,S1,S2,S3);
SIGNAL NS,PS : state_type;
SIGNAL stato : STD_LOGIC;
BEGIN
sync_proc: PROCESS (clk,clrn)
BEGIN
if ((clrn='1')) THEN
PS<=S0;
y <= "00";
elsif (rising_edge(clk)) then
PS <= NS;
CASE PS IS
when S0 =>
if ((x='0'))then
NS <= S0;
y <= "00";
else
NS <= S1;
y <= "11";
end if;
when S1 =>
if (x='0') then
NS <= S2;
y<="10";
else
NS <= S3;
y <= "01";
end if;
when S2 =>
if (x='0') then
NS <= S0;
y <="11";
else
NS <= S1;
y <= "00";
end if;
when S3 =>
if (x='0') then
NS <= S2;
y <="01";
else
NS <= S3;
y <= "10";
end if;
end case;
end if;
end process sync_proc;
END a;
One thing you might not noticed, is that you put both PS (previous state) and NS (next state) in a clocked process. That means registers are inferred for both signals. Thus, NS will be set to PS one clock later that you would probably expect. This can be solved two ways:
1) remove the PS->NS part, and just use state.
sync_proc: PROCESS (clk, clr)
BEGIN
if clr = '1' THEN
state <= S0;
y <= "00";
elsif rising_edge(clk) then
CASE state IS
when S0 =>
if x = '0' then
state <= S0;
y <= "00";
else
state <= S1;
y <= "11";
end if;
when S1 =>
if x = '0' then
state <= S2;
y<="10";
else
state <= S3;
y <= "01";
end if;
when S2 =>
if x = '0' then
state <= S0;
y <="11";
else
state <= S1;
y <= "00";
end if;
when S3 =>
if (x='0') then
state <= S2;
y <="01";
else
state <= S3;
y <= "10";
end if;
end case;
end if;
end process sync_proc;
2) separate the process into a clocked and a combinatorial process.
clk_proc: PROCESS (clk, clr)
BEGIN
if clr = '1' THEN
PS <= S0;
y <= "00";
elsif rising_edge(clk) then
PS <= NS;
y <= next_y;
end if;
end process;
comb_proc : process(PS, x)
begin
CASE PS IS
when S0 =>
if x = '0' then
NS <= S0;
next_y <= "00";
else
NS <= S1;
next_y <= "11";
end if;
when S1 =>
if x = '0' then
NS <= S2;
next_y <= "10";
else
NS <= S3;
next_y <= "01";
end if;
when S2 =>
if x = '0' then
NS <= S0;
next_y <="11";
else
NS <= S1;
next_y <= "00";
end if;
when S3 =>
if x = '0' then
NS <= S2;
next_y <="01";
else
NS <= S3;
next_y <= "10";
end if;
end case;
end process;
Next, I don't understand what you want with reset. The VHDL code is doing exactly what it should do. This is the proper way to use a reset: as long as the reset is asserted, y should display "00". Then, once it is deasserted, y should change on the next clock edge. That is proper design. What the first (AHDL) picture shows is not good: activity of y during reset.
But anyhow, if you are really stubborn, you can get the behavior that is in the first image using some tricks.
sync_proc: PROCESS (clk)
BEGIN
if (rising_edge(clk)) then
if clr = '1' THEN
state <= S0;
y <= "11";
else
case state is
[...]
p.s. you are calling the process sync_proc, as in "synchronous process". But this is not true, as the reset in your code is asynchronous...
p.s.2: give your signals some proper names, instead of e.g. x...

VHDL process get activated when the sensitivity list isn't changing

Process 2 keeps getting activated when there isn't a change. I have a board to test my code, and the state will change when I flip the clock(I set the clock as a button). In my code, the state will only change if I flip Qin. So it isn't doing what I wish it to do, and I spent a lot of time trying to find out what's causing it, but I can't. Please help.
This is the testbench graph TESTBENCH GRAPH
As you can see, in the graph, the output of the PS(present_state) is correct, but in the board, it isn't output right. There is one thing I found that is really important, I tried to output next_state on board, when I flip Qin to '1', the state shows "001", and then I flip clk to '1', the state become "010", which is not suppose to happen. I hope this is an important information.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity VendingMechine is
Port ( Clk : in STD_LOGIC;
Reset : in STD_LOGIC;
Cr : in STD_LOGIC;
Qin : in STD_LOGIC;
S : in STD_LOGIC;
CB : in STD_LOGIC;
W : in STD_LOGIC;
CRo : out STD_LOGIC_VECTOR(1 DOWNTO 0);
Qo : out STD_LOGIC;
PS : out STD_LOGIC_VECTOR(2 DOWNTO 0);
Wo : out STD_LOGIC;
CBo : out STD_LOGIC;
So : out STD_LOGIC);
end VendingMechine;
architecture Behavioral of VendingMechine is
TYPE state IS(Idle, S1, S2, S3, Soda, Candy, Water);
Signal Next_State : state;
Signal Present_State : state := Idle;
begin
Process1:Process(clk, reset)
begin
if(reset = '1') THEN
Present_State <= Idle;
elsif rising_edge(clk) THEN Present_State <= Next_State;
end if;
end process;
Process2:Process(Qin, Present_State, Cr, S, w)
begin
Next_State <= Present_State;
CRo <= "00"; Qo <= '0'; PS <= "000"; Wo <= '0'; CBo <= '0'; So <= '0';
CASE Present_State IS
When Idle =>
PS <= "000";
if Qin='1' Then Next_State <= S1;
else Next_State <= Idle;
end if;
When S1 =>
PS <= "001";
if Qin='1' Then Next_State <= S2;
elsif Cr = '1' Then Cro <= "01"; Next_State <= Idle;
else Next_State <= S1;
end if;
When S2 =>
PS <= "010";
if Qin='1' Then Next_State <= S3;
elsif Cr = '1' Then CRo <="10"; Next_State <= Idle;
elsif S = '1' Then Next_State <= Soda;
elsif CB = '1' Then Next_State <= Candy;
else Next_State <= S2;
end if;
When S3 =>
PS <= "011";
if Cr = '1' Then CRo <= "11"; Next_State <= Idle;
elsif S = '1' Then Qo <= '1'; Next_State <= Soda;
elsif CB = '1' Then Qo <= '1'; Next_State <= Candy;
elsif W = '1' Then Next_State <= Water;
elsif Qin = '1' Then Qo <= '1';
else Next_State <= S3;
end if;
When Soda =>
PS <= "100";
So <= '1';
Next_State <= Idle;
When Candy =>
PS <= "101";
CBo <= '1';
Next_State <= Idle;
When Water =>
PS <= "110";
Wo <= '1';
Next_State <= Idle;
END CASE;
end process;
end Behavioral;
Process will launch not only when signals changes, but every time you assign something to signal, even if it has same value as before. That may be the reason. In parallel process you can't rely on times launch, but on result in case of some conditions, that came in inputs.
Is Qin connected to an external switch? If yes, you should implement clock-domain synchronization (and possible debouncing) on the inputs.
Please let me know in the comments if you don't know how.
Lack of clock-synchronous signals will cause glitches and thus hang-ups in the state-machine. Lack of debouncing will cause multiple switch pulses ("bouncing")

Syntax error with process

I am trying to simulate my small program and I keep getting error messages and I have not been able to figure out why.
The error messages are:
line 131 error near process
line 132 error near behavioral ; expected type void
The lines:
130 end if;
131 end process;
132 end Behavioral;
I have tried to solve these for hours and I still do not have any clue.
Whole code:
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity kuutonen is
Port ( A1 : in STD_LOGIC;
B1 : in STD_LOGIC;
clk : in 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;
G : out STD_LOGIC);
end kuutonen;
architecture Behavioral of kuutonen is
signal tmp : std_logic_vector (2 downto 0);
begin
process (clk)
begin
if(tmp = "110")then
tmp <= "000";
end if;
if (A1 = '0' and B1 = '0') then
if (tmp ="000") then
A <= '1';
B <= '0';
C <= '0';
D <= '0';
E <= '0';
F <= '0';
G <= '0';
tmp <= tmp + 1;
end if;
if (tmp ="001")then
B <= '1';
A <= '0';
C <= '0';
D <= '0';
E <= '0';
F <= '0';
G <= '0';
tmp <= tmp + 1;
end if;
if (tmp ="010")then
C <= '1';
B <= '0';
A <= '0';
D <= '0';
E <= '0';
F <= '0';
G <= '0';
tmp <= tmp + 1;
end if;
if (tmp ="011")then
D <= '1';
B <= '0';
C <= '0';
A <= '0';
E <= '0';
F <= '0';
G <= '0';
E <= '1';
if (tmp ="100")then
E <= '1';
B <= '0';
C <= '0';
D <= '0';
A <= '0';
F <= '0';
G <= '0';
tmp <= tmp+1;
end if;
if (tmp ="101")then
F <= '1';
B <= '0';
C <= '0';
D <= '0';
E <= '0';
A <= '0';
G <= '0';
tmp <= tmp+1;
end if;
if (tmp ="110")then
G <= '1';
B <= '0';
C <= '0';
D <= '0';
E <= '0';
F <= '0';
A <= '0';
end if;
end if;
end process;
end Behavioral;
Just from inspection, I'd say it's probably due to a missing "end if;" between the case for tmp=001 and tmp=100.

Resources