Search code examples
vhdl

Why does VHDL shift register need 2 clock rising_edge to shift?


I'm trying to make a 8-bit shift register using D flipflop. The problem is that when simulating it takes two clock rising edges for the register to shift, one for the D input to change, the other for the Q to change. I don't know why.

entity Registry_8 is
  port (input  : in  std_logic;
        output : out std_logic;
        clk    : in  std_logic;
        clear  : in  std_logic;
        load   : in  std_logic;
        LR     : in  std_logic;
        pIn    : in  std_logic_vector (7 downto 0);
        pOut   : out std_logic_vector (7 downto 0);
        shift  : in  std_logic);
end Registry_8;

architecture Behavioral of Registry_8 is

  component D_flipflop
    port(D, clk, clear, preset : in  std_logic;
         Q, Q_b                : out std_logic);
  end component;
  signal D, Q : std_logic_vector (7 downto 0);

begin

  GEN_FLIP :
  for i in 0 to 7 generate
    D_i : D_flipflop port map(clk => clk, preset => '0', clear => clear, D => D(i), Q => Q(i));
  end generate GEN_FLIP;

  process (clk, load, LR, shift)
  begin
    if (load = '1')
    then D <= pIn;
    end if;
    if (clk'event and clk = '1' and shift = '1')
    then
      if (LR = '0')
      then D(7 downto 0) <= Q(6 downto 0) & input;
           output <= Q(7);
      else
        D(7 downto 0) <= input & Q(7 downto 1);
        output        <= Q(0);
      end if;
    end if;
  end process;
  pOut <= Q;

end Behavioral;

Solution

  • In the process, there is clock edge sensitive condition with the expression:

    clk'event and clk = '1'
    

    The process thereby implements an additional level of sequential logic (flip flops), but you probably wanted to create a process for purely combinatorial design, like:

    process (all) is
    begin
      if (load = '1') then
        D <= pIn;
      end if;
      if shift = '1' then
        if (LR = '0') then
          D(7 downto 0) <= Q(6 downto 0) & input;
          output        <= Q(7);
        else
          D(7 downto 0) <= input & Q(7 downto 1);
          output        <= Q(0);
        end if;
      end if;
    end process;
    

    Note that VHDL-2008 all is used as sensitivity list above, to automatically include all signals used in a process for combinatorial design.