Search code examples
vhdllifo

LIFO memory vhdl code understanding


I have this code for a lifo memory and I don't understand why on 27 line (if(last = n-2) then full <= '1'; end if;) the last signal it's not equal to n-1. If anyone could explain it to me I would really appreciate.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity lifo is
  generic(n : natural := 4);
  port(Din         : in  std_logic_vector(3 downto 0);
       Dout        : out std_logic_vector(3 downto 0);
       wr          : in  std_logic;
       rd          : in  std_logic;
       empty, full : out std_logic;
       clk         : in  std_logic);
end entity lifo;

architecture arh of lifo is
  type memorie is array(0 to n-1) of std_logic_vector(3 downto 0);
  signal mem  : memorie := (others => (others => '0'));
  signal last : integer range -1 to n-1;
begin
  process(clk)
  begin
    if (rising_edge(clk)) and (wr = '1') then
      if (last = n-1) then null;
      else
        if(last = n-2) then full <= '1'; end if;
        if(last = -1) then empty <= '0'; end if;
        mem(last + 1)            <= Din;
        last                     <= last + 1;
      end if;
    elsif (rising_edge(clk)) and (rd = '1') then
      if(last = -1) then null;
      else
        Dout                     <= mem(last);
        last                     <= last - 1; full <= '0';
        if(last = -1) then empty <= '1'; end if;
      end if;
    end if;
  end process;
end architecture arh;

Solution

  • The last is in range -1 to n-1, and when last is n-1 then it indicates full LIFO, and full must be high ('1').

    When a write is accepted, then last is incremented by 1 with last <= last + 1. On the same rising clk edge it is determined if full should go high, which is the case if this write will make the LIFO full. After the write, then last has the value last+1 (the +1 when write is accepted) and LIFO is full if is equals n-1 (with n-1 indicating full). So the condition for full after this write is last+1=n-1, which is then written as last = n-2.

    In addition, it is possible to improve the code in several ways if it does not work right away, e.g. single rising_edge(clk), add reset, skip the null statements through negated condition, add handling of write and read operation in same cycle, remove dead code (the final if).