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

2012-12-3 13:07 5062 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----------------------------------------------     

文章评论1条评论)

登录后参与讨论

用户313253 2010-12-27 14:58

为什么会出现internal error啊,希望知道一下,谢谢
相关推荐阅读
coyoo 2024-12-03 12:20
比较器检测模拟脉冲说明(四)
概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解...
coyoo 2024-11-16 13:54
不同ADC采样同一前端模拟信号时转换用时差异分析
概述 同一组前端模拟信号接入由不同型号ADC组成的模数转换电路时,采样后在FPGA中发现采样用时差异较大。本文主要分析这个时间差异形成的原因,并记录该差异产生对系统造成的影响。系统数字化简介 项目前端...
coyoo 2024-11-10 13:04
ALTERA Cyclone 10器件的使用-7:FPGA片内RAM资源利用率思考
概述 项目使用的FPGA目标器件为Cyclone 10 GX系列规模最大一颗料,由于功能升级增加了功能模块更多,发现器件片内RAM不够使用了。为了探索片内RAM使用的利用率问题,从代码RTL级与编译软...
coyoo 2024-11-10 12:30
转知乎:幽灵般的人体成像技术-PET
幽灵般的人体成像技术——PET - 知乎...
coyoo 2024-11-09 10:26
AD9633默认情况下调试记录(二)
概述 所谓默认情况,即如器件手册中图2所标示那样。对应AD9633的调试,除了涉及到ADC自身,还需要兼顾前端驱动器,系统中AD9633驱动器使用了差分运算放大器,这里不在赘述,笔者已有相关文章论述。...
coyoo 2024-11-07 10:40
AD9633默认情况下调试记录(一)
AD9633在旁路SPI接口时如何在FPGA逻辑中确认字边界概述 AD9633与FPGA之间的LVDS接口初调试,ADC可以通过SPI接口对其内部寄存器进行各项配置。在SPI接口未调通之前,对LVDS...
我要评论
1
10
关闭 站长推荐上一条 /2 下一条