fifo.vhd 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. --+-----------------------------------+-------------------------------------+--
  2. --| ___ ___ | (c) 2013-2014 William R Sowerbutts |--
  3. --| ___ ___ ___ ___( _ ) / _ \ | will@sowerbutts.com |--
  4. --| / __|/ _ \ / __|_ / _ \| | | | | |--
  5. --| \__ \ (_) | (__ / / (_) | |_| | | A Z80 FPGA computer, just for fun |--
  6. --| |___/\___/ \___/___\___/ \___/ | |--
  7. --| | http://sowerbutts.com/ |--
  8. --+-----------------------------------+-------------------------------------+--
  9. --| FIFO implementation with high water mark. Could be improved; currently |--
  10. --| it is impossible to use the last byte in the FIFO (because it cannot |--
  11. --| distinguish completely-full from completely-empty) |--
  12. --+-------------------------------------------------------------------------+--
  13. library IEEE;
  14. use IEEE.std_logic_1164.all;
  15. use IEEE.numeric_std.all;
  16. entity fifo is
  17. generic(
  18. depth_log2 : integer := 10; -- 5 gives 32 bytes, implements without a BRAM.
  19. hwm_space : integer := 5; -- minimum bytes free in buffer before we assert flow control signals
  20. width : integer := 8
  21. );
  22. port(
  23. clk : in std_logic;
  24. reset : in std_logic;
  25. write_en : in std_logic;
  26. write_ready : out std_logic; -- is there space to write?
  27. read_en : in std_logic;
  28. read_ready : out std_logic; -- is there data waiting to read?
  29. data_in : in std_logic_vector(width-1 downto 0);
  30. data_out : out std_logic_vector(width-1 downto 0);
  31. high_water_mark : out std_logic
  32. );
  33. end fifo;
  34. architecture behaviour of fifo is
  35. type fifo_entry is array (natural range <>) of std_logic_vector(width-1 downto 0);
  36. signal fifo_contents : fifo_entry(0 to (2 ** depth_log2) - 1); -- this is the FIFO buffer memory
  37. signal read_ptr : unsigned(depth_log2-1 downto 0) := (others => '0');
  38. signal write_ptr : unsigned(depth_log2-1 downto 0) := (others => '0');
  39. signal full : std_logic;
  40. signal empty : std_logic;
  41. begin
  42. is_empty: process(read_ptr, write_ptr)
  43. begin
  44. if read_ptr = write_ptr then
  45. empty <= '1';
  46. else
  47. empty <= '0';
  48. end if;
  49. if read_ptr = (write_ptr+1) then
  50. full <= '1';
  51. else
  52. full <= '0';
  53. end if;
  54. if (write_ptr - read_ptr) >= ((2 ** depth_log2) - 1 - hwm_space) then
  55. high_water_mark <= '1';
  56. else
  57. high_water_mark <= '0';
  58. end if;
  59. end process;
  60. fifo_update: process(clk)
  61. begin
  62. if rising_edge(clk) then
  63. if reset = '1' then
  64. -- reset
  65. read_ptr <= to_unsigned(0, depth_log2);
  66. write_ptr <= to_unsigned(0, depth_log2);
  67. else
  68. -- normal operation
  69. if write_en = '1' and full = '0' then
  70. fifo_contents(to_integer(write_ptr)) <= data_in;
  71. write_ptr <= write_ptr + 1;
  72. end if;
  73. if read_en = '1' and empty = '0' then
  74. read_ptr <= read_ptr + 1;
  75. end if;
  76. data_out <= fifo_contents(to_integer(read_ptr));
  77. end if;
  78. end if;
  79. end process;
  80. write_ready <= not full;
  81. read_ready <= not empty;
  82. end;