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

📄 freefifo.vhd

📁 常见的输入输出及存储器件(ram及fifo)vhdl实现
💻 VHD
📖 第 1 页 / 共 4 页
字号:
  --  Generate Full
  ---------------------------------------------------------------
  process (wr_clk, reset)
  begin
    if reset='1' then
      full <= '1';
    elsif wr_clk'event and wr_clk='1' then
      if fullg='1' or (almostfullg='1' and wr_allow='1') then
        full <= '1';
      else
        full <= '0';
      end if;
    end if;
  end process;

  full_out <= full;


  ---------------------------------------------------------------
  -- Generate the full, empty, almost full, and almost empty
  -- combinatorial flags
  ---------------------------------------------------------------
  UNDEFINED0: if fpga_type=0 generate
  begin
    emptyg       <= '1' when wr_addr_gray2=rd_addr_gray2 else '0';
    almostemptyg <= '1' when wr_addr_gray2=rd_addr_gray1 else '0';
    fullg        <= '1' when wr_addr_gray2=rd_addr_gray3 else '0';
    almostfullg  <= '1' when wr_addr_gray1=rd_addr_gray3 else '0';
  end generate UNDEFINED0;


  XILINX0: if fpga_type=1 generate
  begin
    ecomp  <= not (wr_addr_gray2 XOR rd_addr_gray2);
    aecomp <= not (wr_addr_gray2 XOR rd_addr_gray1);
    fcomp  <= not (wr_addr_gray2 XOR rd_addr_gray3);
    afcomp <= not (wr_addr_gray1 XOR rd_addr_gray3);

    EMUXCYi: MUXCY_L port map (DI=>always_one,  CI=>always_one, S=>always_one, LO=>ecin);
    EMUXCY0: MUXCY_L port map (DI=>always_zero, CI=>ecin,       S=>ecomp(0),   LO=>emuxcyo(0));
    EMUXCYa: for i in 0 to addr_bits-3 generate
    begin
      EMUXCYb: MUXCY_L port map (DI=>always_zero, CI=>emuxcyo(i), S=>ecomp(i+1), LO=>emuxcyo(i+1));
    end generate EMUXCYa;
    EMUXCYN: MUXCY_L port map (DI=>always_zero,CI=>emuxcyo(addr_bits-2),S=>ecomp(addr_bits-1),LO=>emptyg);

    AEMUXCYi: MUXCY_L port map (DI=>always_one,CI=>always_one,        S=>always_one,      LO=>aecin);
    AEMUXCY0: MUXCY_L port map (DI=>always_zero,CI=>aecin,      S=>aecomp(0),LO=>aemuxcyo(0));
    AEMUXCYa:  for i in 0 to addr_bits-3 generate
    begin
      AEMUXCYb: MUXCY_L port map (DI=>always_zero,CI=>aemuxcyo(i),S=>aecomp(i+1),LO=>aemuxcyo(i+1));
    end generate AEMUXCYa;
    AEMUXCYN: MUXCY_L port map (DI=>always_zero,CI=>aemuxcyo(addr_bits-2),S=>aecomp(addr_bits-1),LO=>almostemptyg);

    FMUXCYi: MUXCY_L port map (DI=>always_one,CI=>always_one,       S=>always_one,     LO=>fcin);
    FMUXCY0: MUXCY_L port map (DI=>always_zero,CI=>fcin,      S=>fcomp(0),LO=>fmuxcyo(0));
    FMUXCYa:  for i in 0 to addr_bits-3 generate
    begin
      FMUXCYb: MUXCY_L port map (DI=>always_zero,CI=>fmuxcyo(i),S=>fcomp(i+1),LO=>fmuxcyo(i+1));
    end generate FMUXCYa;
    FMUXCYn: MUXCY_L port map (DI=>always_zero,CI=>fmuxcyo(addr_bits-2),S=>fcomp(addr_bits-1),LO=>fullg);
    
    AFMUXCYi: MUXCY_L port map (DI=>always_one,CI=>always_one,        S=>always_one,      LO=>afcin);
    AFMUXCY0: MUXCY_L port map (DI=>always_zero,CI=>afcin,      S=>afcomp(0),LO=>afmuxcyo(0));
    AFMUXCYa: for i in 0 to addr_bits-3 generate
      AFMUXCYb:  MUXCY_L port map (DI=>always_zero,CI=>afmuxcyo(i),S=>afcomp(i+1),LO=>afmuxcyo(i+1));
    end generate AFMUXCYa;
    AFMUXCYn: MUXCY_L port map (DI=>always_zero,CI=>afmuxcyo(addr_bits-2),S=>afcomp(addr_bits-1),LO=>almostfullg);
    
  end generate XILINX0;

end arch_fifo_async_xilinx;


----------------------------------------------------------------------------
----------------------------------------------------------------------------
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_async_generic is
    generic (data_bits	:integer;
             addr_bits  :integer;
             block_type	:integer := 0);
    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);
          full		:out std_logic;
          empty		:out std_logic
         );
end fifo_async_generic;

architecture arch_fifo_async_generic of fifo_async_generic is
  signal rd_allow	:std_logic;
  signal wr_allow	:std_logic;
  signal rd_addr	:std_logic_vector (addr_bits-1 downto 0);
  signal rd_addr_gray1	:std_logic_vector (addr_bits-1 downto 0);
  signal wr_addr	:std_logic_vector (addr_bits-1 downto 0);
  signal wr_addr_gray1	:std_logic_vector (addr_bits-1 downto 0);
  signal wr_addr_gray2	:std_logic_vector (addr_bits-1 downto 0);

  signal empty_match	:std_logic;
  signal full_match	:std_logic;
  signal empty_int	:std_logic;
  signal full_int	:std_logic;

  signal always_one   :std_logic;
  signal always_zero  :std_logic;
  
begin
  always_one <= '1';
  always_zero <= '0';

  ---------------------------------------------------------------
  -- Generate the read/write allow signals
  ---------------------------------------------------------------
  rd_allow <= '1' when rd_en='1' and empty_int='0' else '0';
  wr_allow <= '1' when wr_en='1' and 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, wr_addr_gray2, wr_data,
                         rd_clk, rd_addr_gray1, rd_data);

  ---------------------------------------------------------------
  -- Generate the read addresses & pipelined gray-code versions  
  ---------------------------------------------------------------
  process (rd_clk, reset)
    variable addr	:std_logic_vector (rd_addr'range);
  begin
    if reset='1' then
      addr := (others=>'0');
      rd_addr_gray1 <= bin_to_gray (addr);
      addr := addr + 1;
      rd_addr <= addr;
    elsif rd_clk'event and rd_clk='1' then
      if rd_allow='1' then
        rd_addr_gray1 <= bin_to_gray(rd_addr);
        rd_addr <= rd_addr + 1;
      end if;
    end if;
  end process;

  ---------------------------------------------------------------
  --  Generate the write addresses & pipelined gray-code versions
  ---------------------------------------------------------------
  process (wr_clk, reset)
    variable addr	:std_logic_vector (wr_addr'range);
  begin
    if reset='1' then
      addr := (others=>'0');
      wr_addr_gray2 <= bin_to_gray (addr);
      addr := addr + 1;
      wr_addr_gray1 <= bin_to_gray (addr);
      addr := addr + 1;
      wr_addr <= addr;
    elsif wr_clk'event and wr_clk='1' then
      if wr_allow='1' then
        wr_addr_gray2 <= wr_addr_gray1;
        wr_addr_gray1 <= bin_to_gray(wr_addr);
        wr_addr <= wr_addr + 1;
      end if;
    end if;
  end process;
  
  ---------------------------------------------------------------
  -- Generate Empty & Full
  ---------------------------------------------------------------
  empty_match <= '1' when rd_addr_gray1=wr_addr_gray2 else '0';
  full_match  <= '1' when rd_addr_gray1=wr_addr_gray1 else '0';

  process (rd_clk, empty_match)
  begin
    if empty_match='1' then
      empty_int <= '1';
    elsif rd_clk'event and rd_clk='1' then
      empty_int <= empty_match;
    end if;
  end process;

  process (wr_clk, full_match)
  begin
    if full_match='1' then
      full_int <= '1';
    elsif wr_clk'event and wr_clk='1' then
      full_int <= full_match;
    end if;
  end process;

  empty <= empty_int;
  full <= full_int;

end arch_fifo_async_generic;


----------------------------------------------------------------------------
----------------------------------------------------------------------------
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;


entity fifo_async 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);
          full		:out std_logic;
          empty		:out std_logic
         );
end fifo_async;


architecture arch_fifo_async of fifo_async is
begin
  -- Generic FIFO
  UNSPECIFIED0: if fifo_arch=0 generate
  begin
    U1: fifo_async_generic
        generic map (data_bits, addr_bits, block_type)
        port map (reset, wr_clk, wr_en, wr_data, rd_clk, rd_en, rd_data, full, empty);        
  end generate UNSPECIFIED0;

  -- Xilinx XAPP175 without carry logic
  XILINX0: if fifo_arch=1 generate
  begin
    U2: fifo_async_xilinx
        generic map (data_bits, addr_bits, block_type, 0)
        port map (reset, wr_clk, wr_en, wr_data, rd_clk, rd_en, rd_data, full, empty);
  end generate XILINX0;

  -- Xilinx XAPP175 with carry logic
  XILINX1: if fifo_arch=2 generate
  begin
    U3: fifo_async_xilinx
        generic map (data_bits, addr_bits, block_type, 1)
        port map (reset, wr_clk, wr_en, wr_data, rd_clk, rd_en, rd_data, full, empty);
  end generate XILINX1;

end arch_fifo_async;




----------------------------------------------------------------------------
----------------------------------------------------------------------------
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_sync is
    generic (data_bits  :integer;
             addr_bits  :integer;
             block_type :integer := 0);
    port (reset		:in std_logic;
          clk		:in std_logic;
          wr_en		:in std_logic;
          wr_data	:in std_logic_vector (data_bits-1 downto 0);
          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_sync;


architecture arch_fifo_sync of fifo_sync is
  signal wr_addr	:std_logic_vector (addr_bits-1 downto 0);
  signal rd_addr	:std_logic_vector (addr_bits-1 downto 0);
  signal rd_allow	:std_logic;
  signal wr_allow	:std_logic;
  signal count_int	:std_logic_vector (addr_bits-1 downto 0);
  signal empty_int	:std_logic;
  signal full_int	:std_logic;

  signal empty_count	:std_logic_vector (addr_bits-1 downto 0);
  signal aempty_count	:std_logic_vector (addr_bits-1 downto 0);
  signal full_count	:std_logic_vector (addr_bits-1 downto 0);
  signal afull_count	:std_logic_vector (addr_bits-1 downto 0);
  
begin
  count <= count_int;
  full <= full_int;
  empty <= empty_int;

  -- Some constants
  empty_count <= (others=>'0');
  aempty_count <= empty_count + 1;  
  full_count <= (others=>'1');
  afull_count <= full_count - 1;

  ----------------------------------------------
  ----------------------------------------------
  rd_allow <= '1' when rd_en='1' and empty_int='0' else '0';
  wr_allow <= '1' when wr_en='1' and full_int='0' else '0';

  ----------------------------------------------
  ----------------------------------------------
  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,
                clk, wr_allow, wr_addr, wr_data,
                clk, rd_addr, rd_data);

  ----------------------------------------------
  ----------------------------------------------
  process (clk, reset)
  begin
    if reset='1' then
      rd_addr <= (others=>'0');
    elsif clk'event and clk='1' then
      if rd_allow='1' then
        rd_addr <= rd_addr + 1;
      end if;
    end if;
  end process;

  
  ----------------------------------------------
  ----------------------------------------------
  process (clk, reset)
  begin
    if reset='1' then
      wr_addr <= (others=>'0');
    elsif clk'event and clk='1' then
      if wr_allow='1' then
        wr_addr <= wr_addr + 1;
      end if;
    end if;
  end process;


  ----------------------------------------------
  ----------------------------------------------
  process (clk, reset)
  begin
    if reset='1' then
      count_int <= (others=>'0');
    elsif clk'event and clk='1' then
      if wr_allow='0' and rd_allow='1' then
        count_int <= count_int-1;
      elsif wr_allow='1' and rd_allow='0' then
        count_int <= count_int+1;
      end if; -- else count<=count        
    end if;
  end process;

⌨️ 快捷键说明

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