原创 VHDL写的同步FIFO(已调试通过的原代码)

2012-12-3 13:07 5076 10 11 分类: FPGA/CPLD 文集: ALTERA FPGA

------------------------------------------------------------------------------------------
-- Designer        :      Jerry Wang
-- Date            :      2009-3-5
-- Description     :      Synchronous FIFO created by VHDL
-----------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;


entity SFIFO is
       generic(
               FIFOwidth  :      positive :=16;
               depth  :      positive :=45;
               almost_empty_value: positive :=5;
               almost_full_value: positive :=40
               );
              
            
       port
       (
              clk       :      in     std_logic;
              rst       :      in     std_logic;
              wq        :      in     std_logic;
              rq        :      in     std_logic;
              datain    :      in     std_logic_vector(FIFOwidth - 1 downto 0);
              qout      :      out     std_logic_vector(FIFOwidth - 1 downto 0);
              almost_empty:    out   std_logic;
              almost_full:     out   std_logic;
              empty     :      out   std_logic;
              full      :      out   std_logic
       );
end SFIFO;
architecture Behavioral of SFIFO is
------------------------------------
--signal wr_pt: std_logic_vector(15 downto 0);  -- writer pointer counter
signal wr_pt: integer range depth-1 downto 0;
-------------------------------------
--signal rd_pt: std_logic_vector(15 downto 0);  -- read pointer counter
signal rd_pt: integer range depth-1 downto 0;
--------------------------------------
signal empty_t: std_logic;
signal full_t: std_logic;
--------------------------------------
type ram is array(depth - 1 downto 0) of std_logic_vector(FIFOwidth - 1 downto 0);
signal dualram: ram;
signal addra: integer range depth-1 downto 0;--std_logic_vector(15 downto 0);
signal addrb: integer range depth-1 downto 0;--std_logic_vector(15 downto 0);
signal dataout: std_logic_vector(FIFOwidth - 1 downto 0);
---------------------------------------
signal usedw: integer range depth-1 downto 0;--The number of words that are currently in the FIFO
--signal usedw:std_logic_vector(depth - 1 downto 0);
signal almost_empty_t: std_logic;
signal almost_full_t: std_logic;
begin
--  write_pointer is created----------------------------------
process(rst, clk)
begin
  if rst = '1' then
     wr_pt <= 0;--(others => '0');
  elsif clk'event and clk = '1' then
     if wq = '1' and full_t = '0' then
        if rd_pt > wr_pt then
           if rd_pt - wr_pt >1 then
              if wr_pt < depth - 1 then
               wr_pt <= wr_pt + 1;
            else wr_pt <= 0;
            end if;
         end if;
      --end if;    
      else
         if wr_pt - rd_pt /= depth - 1 then
            if wr_pt < depth - 1 then
               wr_pt <= wr_pt + 1;
            else wr_pt <= 0;
            end if;
         end if;  
      end if; 
     end if;
     end if;  
end process;
addra <= wr_pt;


---- read_pointer is created -------------------------------------------------------------
process(rst, clk)
begin
       if rst = '1' then
          rd_pt <= 0;--(others => '0');
       elsif clk'event and clk = '1' then
          if rq = '1' and  empty_t = '0' and rd_pt /= wr_pt then --必须要加最后一个条件,否则读指针不会停止累加。
             if rd_pt < depth-1 then
                rd_pt <= rd_pt +1;
             else rd_pt <= 0;
             end if;
          end if;
       end if;
end process;
addrb <= rd_pt;
-----Calculate the usedw and Generate almost empty and full flag------------------------
process(rst,clk)
begin
       if rst = '1' then
          usedw <= 0;
         
       elsif clk'event and clk = '1' then
          if wq ='1' and rq ='0' and full_t = '0' and usedw < (depth-1) then
             usedw <= usedw + 1;
          elsif wq = '0' and rq = '1' and empty_t = '0' and usedw >0 then
             usedw <= usedw - 1;
          else
             usedw <= usedw;
          end if;  
       end if;
end process;
process(rst,clk)
begin
        if rst = '1' then
           almost_empty_t <= '1';
           almost_full_t <= '0';
        elsif clk'event and clk = '1' then
           if usedw <= almost_empty_value then
              almost_empty_t <= '1';
           else
              almost_empty_t <= '0';
           end if;
           if usedw >= almost_full_value then
              almost_full_t <= '1';
           else
              almost_full_t <= '0';
           end if;         
        end if;
end process;
almost_full <= almost_full_t;
almost_empty <= almost_empty_t;
--FIFO status judge-------------------------------------
process(rst, clk)
begin
  if rst = '1' then
     empty_t <= '1';
  elsif clk'event and clk = '1' then
     if wr_pt = rd_pt then
     empty_t <= '1';
     else
     empty_t <= '0';
     end if;
     end if;
end process;
empty <= empty_t;


process(rst, clk)
begin
  if rst = '1' then
     full_t <= '0';
  elsif clk'event and clk = '1' then
     if wr_pt > rd_pt then
     if (wr_pt - rd_pt) = depth - 1 then
     full_t <= '1';
     else
     full_t <= '0';
     end if;
     else
     if (wr_pt + 1 ) = rd_pt then
     full_t <= '1';
     else
     full_t <= '0';
     end if;
     end if;
  end if;
end process;
 full <= full_t;
-- generate a dual port ram    -----------------------------------------------------------------
process(clk)
begin
  if clk'event and clk = '1' then
   if wq = '1' then
    --dualram(conv_integer(addra)) <= datain;
    dualram(addra) <= datain;
   end if;
  --end if;
 --end process;
 
 --process(clkb)
 --begin
  --if clkb'event and clkb = '1' then
   if rq = '1' then
    --dataout <= dualram(conv_integer(addrb));
    dataout <= dualram(addrb);
   end if;
  end if;
end process;
qout <= dataout;


end Behavioral;
---------------------------------------end of file----------------------------------------------     

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户313253 2010-12-27 14:58

为什么会出现internal error啊,希望知道一下,谢谢
相关推荐阅读
coyoo 2024-12-25 14:13
ALTERA Cyclone 10器件的使用-8:特定的上电顺序
概述 Intel 要求用户为其10代FPGA器件使用特定的上电和掉电顺序,这就要求用户在进行FPGA硬件设计的时候必须选择恰当的FPGA供电方案,并合理控制完整的供电上电顺序。经过在Cyclone 1...
coyoo 2024-12-22 11:46
AD9218子板在新处理板上表现的问题
概述 新的数据处理板融合了数字和数据处理功能模块,计划采用ADI的4通道串行ADC芯片代替之前的并行ADC。由于初次使用,所以初次设计时预留了AD9218的子板的插槽。 在调试AD9633功能的同时并...
coyoo 2024-12-14 17:15
在Cyclone 10 GX器件上实现高精度TDC探索
概述 Cyclone 10 GX器件的ALM结构与Cyclone V类似,所以在Cyclone 10 GX器件上实现TDC功能理论上是可以完全参考甚至移植自Cyclone V系列的成功案例。但是,现实...
coyoo 2024-12-10 13:28
Cyclone V GX FPGA设计TDC的优化问题
概述 通过前面的研究学习,已经可以在CycloneVGX器件中成功实现完整的TDC(或者说完整的TDL,即延时线),测试结果也比较满足,解决了超大BIN尺寸以及大量0尺寸BIN的问题,但是还是存在一些...
coyoo 2024-12-03 12:20
比较器检测模拟脉冲说明(四)
概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解...
coyoo 2024-11-16 13:54
不同ADC采样同一前端模拟信号时转换用时差异分析
概述 同一组前端模拟信号接入由不同型号ADC组成的模数转换电路时,采样后在FPGA中发现采样用时差异较大。本文主要分析这个时间差异形成的原因,并记录该差异产生对系统造成的影响。系统数字化简介 项目前端...
EE直播间
更多
我要评论
1
10
关闭 站长推荐上一条 /3 下一条