FPGA|CPLD|ASIC论坛
直播中

张燕

7年用户 1342经验值
私信 关注
[经验]

VHDL实现基于寄存器的FIFO




无AF,AE标志的FIFO
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;

  4. entity module_fifo_regs_no_flags is
  5.   generic (
  6.     g_WIDTH : natural := 8;
  7.     g_DEPTH : integer := 32
  8.     );
  9.   port (
  10.     i_rst_sync : in std_logic;
  11.     i_clk      : in std_logic;

  12.     -- FIFO Write Interface
  13.     i_wr_en   : in  std_logic;
  14.     i_wr_data : in  std_logic_vector(g_WIDTH-1 downto 0);
  15.     o_full    : out std_logic;

  16.     -- FIFO Read Interface
  17.     i_rd_en   : in  std_logic;
  18.     o_rd_data : out std_logic_vector(g_WIDTH-1 downto 0);
  19.     o_empty   : out std_logic
  20.     );
  21. end module_fifo_regs_no_flags;

  22. architecture rtl of module_fifo_regs_no_flags is

  23.   type t_FIFO_DATA is array (0 to g_DEPTH-1) of std_logic_vector(g_WIDTH-1 downto 0);
  24.   signal r_FIFO_DATA : t_FIFO_DATA := (others => (others => '0'));

  25.   signal r_WR_INDEX   : integer range 0 to g_DEPTH-1 := 0;
  26.   signal r_RD_INDEX   : integer range 0 to g_DEPTH-1 := 0;

  27.   -- # Words in FIFO, has extra range to allow for assert conditions
  28.   signal r_FIFO_COUNT : integer range -1 to g_DEPTH+1 := 0;

  29.   signal w_FULL  : std_logic;
  30.   signal w_EMPTY : std_logic;
  31.    
  32. begin

  33.   p_CONTROL : process (i_clk) is
  34.   begin
  35.     if rising_edge(i_clk) then
  36.       if i_rst_sync = '1' then
  37.         r_FIFO_COUNT <= 0;
  38.         r_WR_INDEX   <= 0;
  39.         r_RD_INDEX   <= 0;
  40.       else

  41.         -- Keeps track of the total number of words in the FIFO
  42.         if (i_wr_en = '1' and i_rd_en = '0') then
  43.           r_FIFO_COUNT <= r_FIFO_COUNT + 1;
  44.         elsif (i_wr_en = '0' and i_rd_en = '1') then
  45.           r_FIFO_COUNT <= r_FIFO_COUNT - 1;
  46.         end if;

  47.         -- Keeps track of the write index (and controls roll-over)
  48.         if (i_wr_en = '1' and w_FULL = '0') then
  49.           if r_WR_INDEX = g_DEPTH-1 then
  50.             r_WR_INDEX <= 0;
  51.           else
  52.             r_WR_INDEX <= r_WR_INDEX + 1;
  53.           end if;
  54.         end if;

  55.         -- Keeps track of the read index (and controls roll-over)        
  56.         if (i_rd_en = '1' and w_EMPTY = '0') then
  57.           if r_RD_INDEX = g_DEPTH-1 then
  58.             r_RD_INDEX <= 0;
  59.           else
  60.             r_RD_INDEX <= r_RD_INDEX + 1;
  61.           end if;
  62.         end if;

  63.         -- Registers the input data when there is a write
  64.         if i_wr_en = '1' then
  65.           r_FIFO_DATA(r_WR_INDEX) <= i_wr_data;
  66.         end if;
  67.          
  68.       end if;                           -- sync reset
  69.     end if;                             -- rising_edge(i_clk)
  70.   end process p_CONTROL;
  71.    
  72.   o_rd_data <= r_FIFO_DATA(r_RD_INDEX);

  73.   w_FULL  <= '1' when r_FIFO_COUNT = g_DEPTH else '0';
  74.   w_EMPTY <= '1' when r_FIFO_COUNT = 0       else '0';

  75.   o_full  <= w_FULL;
  76.   o_empty <= w_EMPTY;
  77.    
  78.   -- ASSERTION LOGIC - Not synthesized
  79.   -- synthesis translate_off

  80.   p_ASSERT : process (i_clk) is
  81.   begin
  82.     if rising_edge(i_clk) then
  83.       if i_wr_en = '1' and w_FULL = '1' then
  84.         report "ASSERT FAILURE - MODULE_REGISTER_FIFO: FIFO IS FULL AND BEING WRITTEN " severity failure;
  85.       end if;

  86.       if i_rd_en = '1' and w_EMPTY = '1' then
  87.         report "ASSERT FAILURE - MODULE_REGISTER_FIFO: FIFO IS EMPTY AND BEING READ " severity failure;
  88.       end if;
  89.     end if;
  90.   end process p_ASSERT;

  91.   -- synthesis translate_on
  92. end rtl;
该版本的Testbench文件
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;

  4. entity module_fifo_regs_no_flags_tb is
  5. end module_fifo_regs_no_flags_tb;

  6. architecture behave of module_fifo_regs_no_flags_tb is

  7.   constant c_DEPTH : integer := 4;
  8.   constant c_WIDTH : integer := 8;
  9.    
  10.   signal r_RESET   : std_logic := '0';
  11.   signal r_CLOCK   : std_logic := '0';
  12.   signal r_WR_EN   : std_logic := '0';
  13.   signal r_WR_DATA : std_logic_vector(c_WIDTH-1 downto 0) := X"A5";
  14.   signal w_FULL    : std_logic;
  15.   signal r_RD_EN   : std_logic := '0';
  16.   signal w_RD_DATA : std_logic_vector(c_WIDTH-1 downto 0);
  17.   signal w_EMPTY   : std_logic;
  18.    
  19.   component module_fifo_regs_no_flags is
  20.     generic (
  21.       g_WIDTH : natural := 8;
  22.       g_DEPTH : integer := 32
  23.       );
  24.     port (
  25.       i_rst_sync : in std_logic;
  26.       i_clk      : in std_logic;

  27.       -- FIFO Write Interface
  28.       i_wr_en   : in  std_logic;
  29.       i_wr_data : in  std_logic_vector(g_WIDTH-1 downto 0);
  30.       o_full    : out std_logic;

  31.       -- FIFO Read Interface
  32.       i_rd_en   : in  std_logic;
  33.       o_rd_data : out std_logic_vector(g_WIDTH-1 downto 0);
  34.       o_empty   : out std_logic
  35.       );
  36.   end component module_fifo_regs_no_flags;

  37.    
  38. begin

  39.   MODULE_FIFO_REGS_NO_FLAGS_INST : module_fifo_regs_no_flags
  40.     generic map (
  41.       g_WIDTH => c_WIDTH,
  42.       g_DEPTH => c_DEPTH
  43.       )
  44.     port map (
  45.       i_rst_sync => r_RESET,
  46.       i_clk      => r_CLOCK,
  47.       i_wr_en    => r_WR_EN,
  48.       i_wr_data  => r_WR_DATA,
  49.       o_full     => w_FULL,
  50.       i_rd_en    => r_RD_EN,
  51.       o_rd_data  => w_RD_DATA,
  52.       o_empty    => w_EMPTY
  53.       );


  54.   r_CLOCK <= not r_CLOCK after 5 ns;

  55.   p_TEST : process is
  56.   begin
  57.     wait until r_CLOCK = '1';
  58.     r_WR_EN <= '1';
  59.     wait until r_CLOCK = '1';
  60.     wait until r_CLOCK = '1';
  61.     wait until r_CLOCK = '1';
  62.     wait until r_CLOCK = '1';
  63.     r_WR_EN <= '0';
  64.     r_RD_EN <= '1';
  65.     wait until r_CLOCK = '1';
  66.     wait until r_CLOCK = '1';
  67.     wait until r_CLOCK = '1';
  68.     wait until r_CLOCK = '1';
  69.     r_RD_EN <= '0';
  70.     r_WR_EN <= '1';
  71.     wait until r_CLOCK = '1';
  72.     wait until r_CLOCK = '1';
  73.     r_RD_EN <= '1';
  74.     wait until r_CLOCK = '1';
  75.     wait until r_CLOCK = '1';
  76.     wait until r_CLOCK = '1';
  77.     wait until r_CLOCK = '1';
  78.     wait until r_CLOCK = '1';
  79.     wait until r_CLOCK = '1';
  80.     wait until r_CLOCK = '1';
  81.     wait until r_CLOCK = '1';
  82.     r_WR_EN <= '0';
  83.     wait until r_CLOCK = '1';
  84.     wait until r_CLOCK = '1';
  85.     wait until r_CLOCK = '1';
  86.     wait until r_CLOCK = '1';

  87.   end process;
  88.    
  89.    
  90. end behave;

加入AF和AE的FIFO
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;

  4. entity module_fifo_regs_with_flags is
  5.   generic (
  6.     g_WIDTH    : natural := 8;
  7.     g_DEPTH    : integer := 32;
  8.     g_AF_LEVEL : integer := 28;
  9.     g_AE_LEVEL : integer := 4
  10.     );
  11.   port (
  12.     i_rst_sync : in std_logic;
  13.     i_clk      : in std_logic;

  14.     -- FIFO Write Interface
  15.     i_wr_en   : in  std_logic;
  16.     i_wr_data : in  std_logic_vector(g_WIDTH-1 downto 0);
  17.     o_af      : out std_logic;
  18.     o_full    : out std_logic;

  19.     -- FIFO Read Interface
  20.     i_rd_en   : in  std_logic;
  21.     o_rd_data : out std_logic_vector(g_WIDTH-1 downto 0);
  22.     o_ae      : out std_logic;
  23.     o_empty   : out std_logic
  24.     );
  25. end module_fifo_regs_with_flags;

  26. architecture rtl of module_fifo_regs_with_flags is

  27.   type t_FIFO_DATA is array (0 to g_DEPTH-1) of std_logic_vector(g_WIDTH-1 downto 0);
  28.   signal r_FIFO_DATA : t_FIFO_DATA := (others => (others => '0'));

  29.   signal r_WR_INDEX   : integer range 0 to g_DEPTH-1 := 0;
  30.   signal r_RD_INDEX   : integer range 0 to g_DEPTH-1 := 0;

  31.   -- # Words in FIFO, has extra range to allow for assert conditions
  32.   signal r_FIFO_COUNT : integer range -1 to g_DEPTH+1 := 0;

  33.   signal w_FULL  : std_logic;
  34.   signal w_EMPTY : std_logic;
  35.    
  36. begin

  37.   p_CONTROL : process (i_clk) is
  38.   begin
  39.     if rising_edge(i_clk) then
  40.       if i_rst_sync = '1' then
  41.         r_FIFO_COUNT <= 0;
  42.         r_WR_INDEX   <= 0;
  43.         r_RD_INDEX   <= 0;
  44.       else

  45.         -- Keeps track of the total number of words in the FIFO
  46.         if (i_wr_en = '1' and i_rd_en = '0') then
  47.           r_FIFO_COUNT <= r_FIFO_COUNT + 1;
  48.         elsif (i_wr_en = '0' and i_rd_en = '1') then
  49.           r_FIFO_COUNT <= r_FIFO_COUNT - 1;
  50.         end if;

  51.         -- Keeps track of the write index (and controls roll-over)
  52.         if (i_wr_en = '1' and w_FULL = '0') then
  53.           if r_WR_INDEX = g_DEPTH-1 then
  54.             r_WR_INDEX <= 0;
  55.           else
  56.             r_WR_INDEX <= r_WR_INDEX + 1;
  57.           end if;
  58.         end if;

  59.         -- Keeps track of the read index (and controls roll-over)        
  60.         if (i_rd_en = '1' and w_EMPTY = '0') then
  61.           if r_RD_INDEX = g_DEPTH-1 then
  62.             r_RD_INDEX <= 0;
  63.           else
  64.             r_RD_INDEX <= r_RD_INDEX + 1;
  65.           end if;
  66.         end if;

  67.         -- Registers the input data when there is a write
  68.         if i_wr_en = '1' then
  69.           r_FIFO_DATA(r_WR_INDEX) <= i_wr_data;
  70.         end if;
  71.          
  72.       end if;                           -- sync reset
  73.     end if;                             -- rising_edge(i_clk)
  74.   end process p_CONTROL;

  75.    
  76.   o_rd_data <= r_FIFO_DATA(r_RD_INDEX);

  77.   w_FULL  <= '1' when r_FIFO_COUNT = g_DEPTH else '0';
  78.   w_EMPTY <= '1' when r_FIFO_COUNT = 0       else '0';

  79.   o_af <= '1' when r_FIFO_COUNT > g_AF_LEVEL else '0';
  80.   o_ae <= '1' when r_FIFO_COUNT < g_AE_LEVEL else '0';
  81.    
  82.   o_full  <= w_FULL;
  83.   o_empty <= w_EMPTY;
  84.    

  85.   -----------------------------------------------------------------------------
  86.   -- ASSERTION LOGIC - Not synthesized
  87.   -----------------------------------------------------------------------------
  88.   -- synthesis translate_off

  89.   p_ASSERT : process (i_clk) is
  90.   begin
  91.     if rising_edge(i_clk) then
  92.       if i_wr_en = '1' and w_FULL = '1' then
  93.         report "ASSERT FAILURE - MODULE_REGISTER_FIFO: FIFO IS FULL AND BEING WRITTEN " severity failure;
  94.       end if;

  95.       if i_rd_en = '1' and w_EMPTY = '1' then
  96.         report "ASSERT FAILURE - MODULE_REGISTER_FIFO: FIFO IS EMPTY AND BEING READ " severity failure;
  97.       end if;
  98.     end if;
  99.   end process p_ASSERT;

  100.   -- synthesis translate_on
  101.      
  102.    
  103. end rtl;
该版本的Testbench文件
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;

  4. entity module_fifo_regs_with_flags_tb is
  5. end module_fifo_regs_with_flags_tb;

  6. architecture behave of module_fifo_regs_with_flags_tb is

  7.   constant c_DEPTH    : integer := 4;
  8.   constant c_WIDTH    : integer := 8;
  9.   constant c_AF_LEVEL : integer := 2;
  10.   constant c_AE_LEVEL : integer := 2;

  11.   signal r_RESET   : std_logic := '0';
  12.   signal r_CLOCK   : std_logic := '0';
  13.   signal r_WR_EN   : std_logic := '0';
  14.   signal r_WR_DATA : std_logic_vector(c_WIDTH-1 downto 0) := X"A5";
  15.   signal w_AF      : std_logic;
  16.   signal w_FULL    : std_logic;
  17.   signal r_RD_EN   : std_logic := '0';
  18.   signal w_RD_DATA : std_logic_vector(c_WIDTH-1 downto 0);
  19.   signal w_AE      : std_logic;
  20.   signal w_EMPTY   : std_logic;
  21.    
  22.   component module_fifo_regs_with_flags is
  23.     generic (
  24.       g_WIDTH    : natural := 8;
  25.       g_DEPTH    : integer := 32;
  26.       g_AF_LEVEL : integer := 28;
  27.       g_AE_LEVEL : integer := 4
  28.       );
  29.     port (
  30.       i_rst_sync : in std_logic;
  31.       i_clk      : in std_logic;

  32.       -- FIFO Write Interface
  33.       i_wr_en   : in  std_logic;
  34.       i_wr_data : in  std_logic_vector(g_WIDTH-1 downto 0);
  35.       o_af      : out std_logic;
  36.       o_full    : out std_logic;

  37.       -- FIFO Read Interface
  38.       i_rd_en   : in  std_logic;
  39.       o_rd_data : out std_logic_vector(g_WIDTH-1 downto 0);
  40.       o_ae      : out std_logic;
  41.       o_empty   : out std_logic
  42.       );
  43.   end component module_fifo_regs_with_flags;

  44.    
  45. begin

  46.   MODULE_FIFO_REGS_WITH_FLAGS_INST : module_fifo_regs_with_flags
  47.     generic map (
  48.       g_WIDTH    => c_WIDTH,
  49.       g_DEPTH    => c_DEPTH,
  50.       g_AF_LEVEL => c_AF_LEVEL,
  51.       g_AE_LEVEL => c_AE_LEVEL
  52.       )
  53.     port map (
  54.       i_rst_sync => r_RESET,
  55.       i_clk      => r_CLOCK,
  56.       i_wr_en    => r_WR_EN,
  57.       i_wr_data  => r_WR_DATA,
  58.       o_af       => w_AF,
  59.       o_full     => w_FULL,
  60.       i_rd_en    => r_RD_EN,
  61.       o_rd_data  => w_RD_DATA,
  62.       o_ae       => w_AE,
  63.       o_empty    => w_EMPTY
  64.       );

  65.   r_CLOCK <= not r_CLOCK after 5 ns;

  66.   p_TEST : process is
  67.   begin
  68.     wait until r_CLOCK = '1';
  69.     r_WR_EN <= '1';
  70.     wait until r_CLOCK = '1';
  71.     wait until r_CLOCK = '1';
  72.     wait until r_CLOCK = '1';
  73.     wait until r_CLOCK = '1';
  74.     r_WR_EN <= '0';
  75.     r_RD_EN <= '1';
  76.     wait until r_CLOCK = '1';
  77.     wait until r_CLOCK = '1';
  78.     wait until r_CLOCK = '1';
  79.     wait until r_CLOCK = '1';
  80.     r_RD_EN <= '0';
  81.     r_WR_EN <= '1';
  82.     wait until r_CLOCK = '1';
  83.     wait until r_CLOCK = '1';
  84.     r_RD_EN <= '1';
  85.     wait until r_CLOCK = '1';
  86.     wait until r_CLOCK = '1';
  87.     wait until r_CLOCK = '1';
  88.     wait until r_CLOCK = '1';
  89.     wait until r_CLOCK = '1';
  90.     wait until r_CLOCK = '1';
  91.     wait until r_CLOCK = '1';
  92.     wait until r_CLOCK = '1';
  93.     r_WR_EN <= '0';
  94.     wait until r_CLOCK = '1';
  95.     wait until r_CLOCK = '1';
  96.     wait until r_CLOCK = '1';
  97.     wait until r_CLOCK = '1';

  98.   end process;
  99.    
  100. end behave;


更多回帖

发帖
×
20
完善资料,
赚取积分