⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 freefifo.vhd

📁 常见的输入输出及存储器件(ram及fifo)vhdl实现
💻 VHD
📖 第 1 页 / 共 4 页
字号:

  ----------------------------------------------
  ----------------------------------------------
  process (clk, reset)
  begin
    if reset='1' then
      empty_int <= '1';
    elsif clk'event and clk='1' then
      if empty_int='1' and wr_allow='1' then
        empty_int <= '0';
      elsif count_int=aempty_count and rd_allow='1' and wr_allow='0' then
        empty_int <= '1';
      elsif count_int=empty_count then
        empty_int <= '1';
      else
        empty_int <= '0';
      end if;
    end if;
  end process;


  ----------------------------------------------
  ----------------------------------------------
  process (clk, reset)
  begin
    if reset='1' then
      full_int <= '0';
    elsif clk'event and clk='1' then
      if full_int='1' and rd_allow='1' then
        full_int <= '0';
      elsif count_int=afull_count and rd_allow='0' and wr_allow='1' then
        full_int <= '1';
      elsif count_int=full_count then
        full_int <= '1';
      else
        full_int <= '0';
      end if;
    end if;
  end process;

end arch_fifo_sync;




----------------------------------------------------------------------------
--  This is basically a test model.  It shows that the wrcount and rdcount
--  FIFO's are really made up of two seperate FIFO's.  But since the *_orig
--  FIFO's are slightly different than the "normal" ones, they are not
--  "pin" compatible.   The *_orig FIFO's are included here as reference
--  and "prior art".
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_fifo.all;
use work.ram_lib.all;


entity fifo_wrcount_orig is
    generic (data_bits	:integer;
             addr_bits  :integer;
             block_type	:integer := 0;
             fifo_arch  :integer := 0); -- 0=Generic architecture, 1=Xilinx, 2=Xilinx w/carry
    port (reset		:in  std_logic;
          wr_clk	:in  std_logic;
          wr_en		:in  std_logic;
          wr_data	:in  std_logic_vector (data_bits-1 downto 0);
          rd_clk	:in  std_logic;
          rd_en		:in  std_logic;
          rd_data	:out std_logic_vector (data_bits-1 downto 0);
          count		:out std_logic_vector (addr_bits-1 downto 0);
          full		:out std_logic;
          empty		:out std_logic
         );
end fifo_wrcount_orig;

architecture arch_fifo_wrcount_orig of fifo_wrcount_orig is
  signal i_rd_en	:std_logic;
  signal i_rd_en2	:std_logic;
  signal i_wr_en	:std_logic;
  signal i_data1	:std_logic_vector (data_bits-1 downto 0);
  signal i_data2	:std_logic_vector (data_bits-1 downto 0);
  signal i_data3	:std_logic_vector (data_bits-1 downto 0);
  signal i_count	:std_logic_vector (addr_bits-1 downto 0);
  signal i_full1	:std_logic;
  signal i_empty1	:std_logic;
  signal i_full2	:std_logic;
  signal i_empty2	:std_logic;
  signal temp_valid	:std_logic;
  signal count_max 	:std_logic_vector (addr_bits-1 downto 0);

begin
  count_max <= (others=>'1');
  
  -- Misc signals
  full <= i_full1;
  empty <= i_empty2;
  count <= count_max - i_count;

  -- The Input FIFO
  U1: fifo_sync
        generic map (data_bits, addr_bits, block_type)
        port map (reset, wr_clk, wr_en, wr_data,
                  i_rd_en, i_data1, i_count, i_full1, i_empty1);

  -- The output FIFO
  U2: fifo_async
        generic map (data_bits, addr_bits, block_type, fifo_arch)
        port map (reset,
                  wr_clk, i_wr_en, i_data3,
                  rd_clk, rd_en, rd_data, i_full2, i_empty2);
                  

  -- Generate the read enables
  i_rd_en <= '1' when i_empty1='0' and i_full2='0' else '0';

  process (reset, wr_clk)
  begin
    if reset='1' then
      i_rd_en2 <= '0';
    elsif wr_clk'event and wr_clk='1' then
      i_rd_en2 <= i_rd_en;
    end if;
  end process;

  -- Latch the data into a temp buffer if the read FIFO is full
  process (reset, wr_clk)
  begin
    if reset='1' then
      i_data2 <= (others=>'0');
    elsif wr_clk'event and wr_clk='1' then
      if i_full2='1' and i_rd_en2='1' then
        i_data2 <= i_data1;
      end if;
    end if;
  end process;

  -- Track if the temp buffer is being used
  process (reset, wr_clk)
  begin
    if reset='1' then
      temp_valid<='0';
    elsif wr_clk'event and wr_clk='1' then
      if i_full2='1' and i_rd_en2='1' then
        temp_valid <= '1';
      elsif i_full2='0' then
        temp_valid <= '0';
      end if;
    end if;
  end process;
  

  -- Generate the write enable signal
  i_wr_en <= '1' when temp_valid='1' else
             '1' when i_rd_en2='1'   else
             '0';
        
  -- Generate the input data to the read fifo
  i_data3 <= i_data1 when temp_valid='0' else i_data2;


end arch_fifo_wrcount_orig;


----------------------------------------------------------------------------
--  This is basically a test model.  It shows that the wrcount and rdcount
--  FIFO's are really made up of two seperate FIFO's.  But since the *_orig
--  FIFO's are slightly different than the "normal" ones, they are not
--  "pin" compatible.   The *_orig FIFO's are included here as reference
--  and "prior art".
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_fifo.all;
use work.ram_lib.all;


entity fifo_rdcount_orig is
    generic (data_bits	:integer;
             addr_bits  :integer;
             block_type	:integer := 0;
             fifo_arch  :integer := 0); -- 0=Generic architecture, 1=Xilinx, 2=Xilinx w/carry
    port (reset		:in  std_logic;
          wr_clk	:in  std_logic;
          wr_en		:in  std_logic;
          wr_data	:in  std_logic_vector (data_bits-1 downto 0);
          rd_clk	:in  std_logic;
          rd_en		:in  std_logic;
          rd_data	:out std_logic_vector (data_bits-1 downto 0);
          count		:out std_logic_vector (addr_bits-1 downto 0);
          full		:out std_logic;
          empty		:out std_logic
         );
end fifo_rdcount_orig;

architecture arch_fifo_rdcount_orig of fifo_rdcount_orig is
  signal i_rd_en	:std_logic;
  signal i_rd_en2	:std_logic;
  signal i_wr_en	:std_logic;
  signal i_data1	:std_logic_vector (data_bits-1 downto 0);
  signal i_data2	:std_logic_vector (data_bits-1 downto 0);
  signal i_data3	:std_logic_vector (data_bits-1 downto 0);
  signal i_count	:std_logic_vector (addr_bits-1 downto 0);
  signal i_full1	:std_logic;
  signal i_empty1	:std_logic;
  signal i_full2	:std_logic;
  signal i_empty2	:std_logic;
  signal temp_valid	:std_logic;

begin
  -- Misc signals
  full <= i_full1;
  empty <= i_empty2;
  count <= i_count;

  -- The Input FIFO
  U1: fifo_async
        generic map (data_bits, addr_bits, block_type, fifo_arch)
        port map (reset,
                  wr_clk, wr_en, wr_data,
                  rd_clk, i_rd_en, i_data1, i_full1, i_empty1);
                  

  -- The output FIFO
  U2: fifo_sync
        generic map (data_bits, addr_bits, block_type)
        port map(reset, rd_clk, i_wr_en, i_data3,
                 rd_en, rd_data, i_count, i_full2, i_empty2);
                
  -- Generate the read enables
  i_rd_en <= '1' when i_empty1='0' and i_full2='0' else '0';

  process (reset, rd_clk)
  begin
    if reset='1' then
      i_rd_en2 <= '0';
    elsif rd_clk'event and rd_clk='1' then
      i_rd_en2 <= i_rd_en;
    end if;
  end process;

  -- Latch the data into a temp buffer if the read FIFO is full
  process (reset, rd_clk)
  begin
    if reset='1' then
      i_data2 <= (others=>'0');
    elsif rd_clk'event and rd_clk='1' then
      if i_full2='1' and i_rd_en2='1' then
        i_data2 <= i_data1;
      end if;
    end if;
  end process;

  -- Track if the temp buffer is being used
  process (reset, rd_clk)
  begin
    if reset='1' then
      temp_valid<='0';
    elsif rd_clk'event and rd_clk='1' then
      if i_full2='1' and i_rd_en2='1' then
        temp_valid <= '1';
      elsif i_full2='0' then
        temp_valid <= '0';
      end if;
    end if;
  end process;
  

  -- Generate the write enable signal
  i_wr_en <= '1' when temp_valid='1' else
             '1' when i_rd_en2='1'   else
             '0';
        
  -- Generate the input data to the read fifo
  i_data3 <= i_data1 when temp_valid='0' else i_data2;


end arch_fifo_rdcount_orig;

----------------------------------------------------------------------------
----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library work;
use work.free_fifo.all;
use work.ram_lib.all;


entity fifo_wrcount is
    generic (data_bits	:integer;
             addr_bits  :integer;
             block_type	:integer := 0;
             async_size :integer := 16); 
    port (reset		:in  std_logic;
          wr_clk	:in  std_logic;
          wr_en		:in  std_logic;
          wr_data	:in  std_logic_vector (data_bits-1 downto 0);
          rd_clk	:in  std_logic;
          rd_en		:in  std_logic;
          rd_data	:out std_logic_vector (data_bits-1 downto 0);
          count		:out std_logic_vector (addr_bits-1 downto 0);
          full		:out std_logic;
          empty		:out std_logic
         );
end fifo_wrcount;

architecture arch_fifo_wrcount of fifo_wrcount is
  signal wrptr_bin	:std_logic_vector (addr_bits-1 downto 0);
  signal wrptr		:std_logic_vector (addr_bits-1 downto 0);
  signal wrptr1		:std_logic_vector (addr_bits-1 downto 0);

  signal rdptr_bin	:std_logic_vector (addr_bits-1 downto 0);
  signal rdptr		:std_logic_vector (addr_bits-1 downto 0);
  signal rdptr_max	:std_logic_vector (addr_bits-1 downto 0);
  signal rdptr_max_bin	:std_logic_vector (addr_bits-1 downto 0);

  signal midptr_bin	:std_logic_vector (addr_bits-1 downto 0);
  signal midptr 	:std_logic_vector (addr_bits-1 downto 0);
  signal midptr1	:std_logic_vector (addr_bits-1 downto 0);

  signal wf_count	:std_logic_vector (addr_bits-1 downto 0);
  
  signal wf_full_match	:std_logic;
  signal wf_empty_match	:std_logic;
  signal wf_aempty_match:std_logic;
  signal rf_full_match	:std_logic;
  signal rf_empty_match	:std_logic;

  signal wf_full_int	:std_logic;
  signal wf_empty_int	:std_logic;
  signal rf_full_int	:std_logic;
  signal rf_empty_int	:std_logic;
  
  signal rd_allow	:std_logic;
  signal wr_allow	:std_logic;
  signal mid_allow	:std_logic;

begin
  empty <= rf_empty_int;
  full <= wf_full_int;
  count <= wf_count;

  ---------------------------------------------------------------
  -- Generate the read/write allow signals
  ---------------------------------------------------------------
  rd_allow <= '1' when rd_en='1' and rf_empty_int='0' else '0';
  wr_allow <= '1' when wr_en='1' and wf_full_int='0' else '0';
  mid_allow <= '1' when wf_empty_int='0' and rf_full_int='0' else '0';

  ---------------------------------------------------------------
  -- Instantiate the RAM
  ---------------------------------------------------------------
  fifo_ram: ram_dp
               generic map (addr_bits => addr_bits,
                            data_bits => data_bits,
                            register_out_flag => 1,
                            block_type => block_type)
               port map (reset,
                         wr_clk, wr_allow, wrptr, wr_data,
                         rd_clk, rdptr, rd_data);

  ---------------------------------------------------------------
  --  Generate the write addresses
  ---------------------------------------------------------------
  process (wr_clk, reset)
    variable addr	:std_logic_vector (wrptr_bin'range);
  begin
    if reset='1' then
      addr := (others=>'0');
      wrptr <= bin_to_gray (addr);
      addr := addr + 1;
      wrptr1 <= bin_to_gray (addr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -