Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Sequence Detector Using Shift Registers

I am trying to implement a Sequence Detector that will detect a succession of four 0's or four 1's. This is for a lab using the DE1 Development board. The main problem that I see is that reg_in in the shift register portion of the code is only seeing a 0. This means that only the Zero detecting shift register sees the four 0's. Below is the code, a snapshot of the simulation and how Quartus II is synthesizing the shift register from my code into the circuit. Any help would be appreciated. Thanks!

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY part3 IS

PORT ( SW : IN STD_LOGIC_VECTOR( 1 DOWNTO 0 );

KEY : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

LEDR : OUT STD_LOGIC_VECTOR( 7 DOWNTO 0 );

LEDG : OUT STD_LOGIC_VECTOR(0 DOWNTO 0));

END ENTITY;

ARCHITECTURE Behavior OF part3 IS

COMPONENT shft_reg IS --See component description below

PORT ( clock, reset_n : IN STD_LOGIC;

R : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

reg_in : BUFFER STD_LOGIC;

reg_out: BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));

END COMPONENT;

SIGNAL Zreg_out, Oreg_out : STD_LOGIC_VECTOR(3 DOWNTO 0);

SIGNAL FourZeros, FourOnes : STD_LOGIC;

SIGNAL SRg_in : STD_LOGIC;

BEGIN

SRg_in <= SW(1);

Z_SReg : shft_reg

PORT MAP (KEY(0), SW(0), "1111", SRg_in, Zreg_out);

O_SReg : shft_reg

PORT MAP (KEY(0), SW(0), "0000", SRg_in, Oreg_out);

FourZeros <= NOT((Zreg_out(0))OR(Zreg_out(1))OR(Zreg_out(2))OR(Zreg_out(3)));

FourOnes <= ((Oreg_out(0))AND(Oreg_out(1))AND(Oreg_out(2))AND(Oreg_out(3)));

LEDG(0) <= FourZeros OR FourOnes; --The output of the Shift Registers is used in a

LEDR(7 DOWNTO 4) <= Zreg_out(3 DOWNTO 0);

LEDR(3 DOWNTO 0) <= Oreg_out(3 DOWNTO 0);

--four input Negative-OR gate and a four input AND

END Behavior; --respectively to detect the four consecutive logic levels

library IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY shft_reg IS

PORT ( clock, reset_n : IN STD_LOGIC;

R : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

reg_in : BUFFER STD_LOGIC;

reg_out: BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));

END shft_reg;

ARCHITECTURE Behavior OF shft_reg IS --Two Shift Registers will be used to detect four

SIGNAL regin : STD_LOGIC; --consecutive zeroes or ones

SIGNAL sreg : STD_LOGIC_VECTOR (3 DOWNTO 0); --This is done by first resetting them to all ones

--(in the case of the zero detector), or all zeroes

BEGIN

--(in the case of the ones detector)

PROCESS (clock, reset_n, R, reg_in) --The output of these Shift Registers is gated above.

BEGIN

IF (reset_n = '0') THEN

sreg <= R;

reg_in <= '0';

ELSIF ((clock'EVENT) and (clock = '1')) THEN

sreg(3) <= sreg(2);

sreg(2) <= sreg(1);

sreg(1) <= sreg(0);

sreg(0) <= reg_in;

END IF;

END PROCESS;

reg_out <= sreg;

END Behavior;

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Replace the 'buffer' in the port declarations by the appropriate 'in' or or 'out'.

    Recompile and then correct the error that will show up.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If you have to instantiate shift registers for study then fair enough but a compact way to detect any sequence without using explicit shift register or state machines is to register your input on a proper clock as many times as needed and read all delayed stages.

    Using key as clock is not right.

    to detect "000" or "1111" of input sw:

    
    --in a clk process
    sw_1d <= sw;
    sw_2d <= sw_1d;
    sw_3d <= sw_2d;
    if sw = '0' and sw_1d = '0' and sw_2d = '0' and sw_3d = '0' then
         zeros <= '1';
    elsif sw = '1' and sw_1d = '1' and sw_2d = '1' and sw_3d = '1' then
         ones <= '1';
    else
         zeros <= '0';
         ones <= '0';
    end if