What is the system that I want to design? I assume that I have an input sequence of bits, arriving at the input port, one bit a time. Whenever the last 4 bits has the value "1011", I want a single pulse to be generated at the output port.
State Machine Diagram:
The following state machine diagram shows how this works. The VHDL code shared further down in the article is a direct implementation of this state diagram. You can see that the initial state is called "A" and as each incoming bit matches the bit in the sequence "1011", we move to the next state, finally arriving at state "D". The output pulse is generated if the next input bit is '1', matching with the right most bit in the sequence, "1011".
library ieee; use ieee.std_logic_1164.all; --Sequence detector for detecting the sequence "1011". --Non overlapping type. entity sequence_detector is port(clk : in std_logic; --clock signal reset : in std_logic; --reset signal bit_in : in std_logic; --serial bit input seq_detected : out std_logic --A '1' indicates the pattern "1011" is detected in the sequence. ); end sequence_detector; architecture Behavioral of sequence_detector is type state_type is (A,B,C,D); --Defines the type for states in the state machine signal state : state_type := A; --Declare the signal with the corresponding state type. begin process(clk,reset) begin if(reset = '1') then --resets state and output signal when reset is asserted. seq_detected <= '0'; state <= A; --initial state elsif(rising_edge(clk)) then --calculates the next state based on current state and input bit. case state is when A => --when the current state is A. seq_detected <= '0'; if(bit_in = '0') then state <= A; else state <= B; --first bit matches with the 1st bit in "1011" from left. end if; when B => --when the current state is B. if(bit_in = '0') then state <= C; --2nd bit matches with the 2nd bit in "1011" from left. else state <= B; end if; when C => --when the current state is C. if(bit_in = '0') then state <= A; else state <= D; --3rd bit matches with the 3rd bit in "1011" from left. end if; when D => --when the current state is D. if(bit_in = '0') then state <= C; else state <= A; --assert pulse on output signal seq_detected <= '1'; --4th bit matches with the final bit in "1011". end if; when others => NULL; end case; end if; end process; end Behavioral;
I believe that the code is well commented, so I wont explain it any further. Note that, the output depends on the current state and the current input. So what we have just implemented is a Mealy state machine.
The following testbench code was written for testing the code. The sequence "11011101011" was sent to our sequence detector entity, one bit at a time starting from the leftmost bit.
What we are trying to detect is the 4 bit sequence "1011". So an output pulse should be generated on the 5th and the 11th input bit.
My input sequence: "11011101011".
Testbench Code for Sequence Detector:
library ieee; use ieee.std_logic_1164.all; entity tb_sequence_detector is end tb_sequence_detector; architecture Behavioral of tb_sequence_detector is signal clk,reset,bit_in,seq_detected : std_logic := '0'; constant clk_period : time := 10 ns; begin -- entity instantiation with named association uut: entity work.sequence_detector port map ( clk => clk, reset => reset, bit_in => bit_in, seq_detected => seq_detected ); -- generate clock clk_process :process begin wait for clk_period/2; clk <= not clk; end process; -- stimulus process : apply the bits in the sequence one by one. stim_proc: process begin bit_in <= '1'; --1 wait for clk_period; bit_in <= '1'; --11 wait for clk_period; bit_in <= '0'; --110 wait for clk_period; bit_in <= '1'; --1101 wait for clk_period; bit_in <= '1'; --11011 wait for clk_period; bit_in <= '1'; --110111 wait for clk_period; bit_in <= '0'; --1101110 wait for clk_period; bit_in <= '1'; --11011101 wait for clk_period; bit_in <= '0'; --110111010 wait for clk_period; bit_in <= '1'; --1101110101 wait for clk_period; wait; end process; end Behavioral;
Simulation Waveform:
The simulated waveform from modelsim is pasted below:
Note:- The code was simulated using modelsim. It was synthesised successfully using AMD Vivado 2023.2 version.