日志档案

发表于 2007-2-4 20:37:23

8

标签: FIFO  VHDL  

同步FIFO之VHDL描述5(大结局)

同步FIFOVHDL描述5

       昨天晚上把所有的模块描述都完成了,同时还完成了双端口RAM的后仿真,从目前的仿真结果来看,应该没有什么问题。今天的任务就是把这些模块组装起来并完成前后仿真,这样同步FIFOVHDL描述就算全部完成了。按照前面的思路和框图,把这些模块组装起来应该很简单,下面就直接给出VHDL代码。当然组装的过程还要排查除了双口RAM以外电路的代码描述有没有问题,如果有问题的话就就地改正了,呵呵。

       在代码的集成和仿真的时候还真发现了一些问题,主要包括数据的寄存,以及空满状态判断上,最后的代码使用Quartus II6.0综合和布局布线,选用的是CycloneII系列的器件,并用Modelsim进行了功能仿真和时序仿真,两种仿真均通过。下面主要是集成的定层文件和时序仿真图(图1,图2,图3,图4,图5

 

---------------------------------------------------------------------------------------------------------

-- Designer            :      skycanny

-- Date                  :      2007-2-4

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

       (

              width      :      positive   := 16;

              depth      :      positive   := 8

       );

       port

       (

              clk          :      in     std_logic;

              rst          :      in     std_logic;

              wq          :      in     std_logic;

              rq           :      in     std_logic;

              data :      in     std_logic_vector(width - 1 downto 0);

              q            :      out   std_logic_vector(width - 1 downto 0);

              empty     :      out   std_logic;

              full   :      out   std_logic

       );

end entity sfifo;

-----------------------------------------------------------------------------------------------------------

architecture structure of sfifo is

signal      empty_t   :      std_logic;

signal      full_t       :      std_logic;

signal      wr_pt      :      std_logic_vector(depth - 1 downto 0);

signal      rd_pt       :      std_logic_vector(depth - 1 downto 0);

signal      wr          :      std_logic;

signal      rd           :      std_logic;

component write_pointer

       generic

       (

              depth      :      positive   :=8  

       );

       port

       (

              clk          :      in     std_logic;

              rst          :      in     std_logic;

              wq          :      in     std_logic;

              full          :      in     std_logic;

              wr          :      out   std_logic;

              wr_pt      :      out   std_logic_vector(depth - 1 downto 0)         

       );

end component;

component read_pointer

       generic

       (

              depth      :      positive   :=8  

       );

       port

       (

              clk          :      in     std_logic;

              rst          :      in     std_logic;

              rq           :      in     std_logic;

              empty     :      in     std_logic;

              rd           :      out   std_logic;

              rd_pt       :      out   std_logic_vector(depth - 1 downto 0)         

       );

end component;

 

component judge_status

       generic

       (

              depth      :      positive :=8

       );

       port

       (

              clk          :      in     std_logic;

              rst          :      in     std_logic;

              wr_pt      :      in     std_logic_vector(depth - 1 downto 0);

              rd_pt       :      in     std_logic_vector(depth - 1 downto 0);

              empty     :      out   std_logic;

              full   :      out   std_logic

       );

end component;

component dualram

       generic

       (

              width      :      positive   := 16;

              depth      :      positive   := 8

       );

       port

       (

              ------------------------- port a is only for writing -------------------------------

              clka :      in     std_logic;

              wr          :      in     std_logic;

              addra      :      in     std_logic_vector(depth - 1 downto 0);

              datain      :      in     std_logic_vector(width - 1 downto 0);

              ------------------------------------------------------------------------------------

              ------------------------- port b is only for reading -------------------------------

              clkb :      in     std_logic;

              rd           :      in     std_logic;

              addrb      :      in     std_logic_vector(depth - 1 downto 0);

              dataout    :      out   std_logic_vector(width - 1 downto 0)         

              ------------------------------------------------------------------------------------

       );

end component;

begin

       empty <= empty_t;

       full <= full_t;

       u0    :      dualram

       generic map

       (

              width => width,

              depth => depth

       )

       port map

       (

              --------=>

        clka        => clk,

        wr          => wr,

        addra      => wr_pt,

        datain      => data,

        --------=>

        --------=>

        clkb => clk,

        rd           => rd,

        addrb      => rd_pt,

        dataout    => q

       );

u1    :      write_pointer

       generic map

       (

              depth => depth

       )

       port map

       (

              clk          => clk,

           rst          => rst,

           wq          => wq,

           full          => full_t,

           wr          => wr,

           wr_pt      => wr_pt

       );

      

       u2    :      read_pointer

       generic map

       (

              depth => depth

       )

       port map

       (

              clk          => clk,   

           rst          => rst,

           rq           => rq,

           empty     => empty_t,

           rd           => rd,

           rd_pt       => rd_pt                       

       );

      

       u3    :      judge_status

       generic map

       (

              depth => depth

       )

       port map

       (

              clk          => clk,

           rst          => rst,

           wr_pt      => wr_pt,

           rd_pt       => rd_pt,

           empty     => empty_t,

           full   => full_t 

       );

       end structure;

 

点击看大图

                                                                

                                                          图1 时序仿真图全貌

 

点击看大图

 

                                                                2写数据到空的FIFO

 

点击看大图

                                                                                                                               3 FIFO被写满

 

点击看大图

                                                                                                                             4 FIFO被读空

 

点击看大图

                                                                       

                                                                   图5 同时对FIFO进行读写

 

从上面的时序仿真图来看,同步FIFOVHDL描述满足设计要求,可以在需要应用到的地方直接调用,同时支持参数话的调用,以满足不同的应用需求。大家如果有什么关于这个FIFO实现的问题可以直接提问,我回尽快回复,另外不要忘了投票哟。最后欢迎大家访问skycanny的笔记(副站)

 

 

 

 

 

 

系统分类: CPLD/FPGA   |   用户分类: FPGA/CPLD   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(1815)    回复(6)  

投一票您将和博主都有获奖机会!

  • riple

    2007-2-5 14:29:17

    非常好。有下面几个建议:

    1. 用RTL Viewer把顶层的RTL框图展示一下,有助于阅读代码。

    2. 一般的fifo都会提供半空和半满标志。如果操作这个fifo的控制器对empty和full信号有一定的判断延迟的话,可能会产生对空fifo的读操作或对满fifo的写操作。为了灵活,你可以提供一个“有效字节数”的顶层端口,通过fifo中有效的字节数和fifo容量的比较就可以指示是否可以对fifo进行操作。

    3. 用empty信号屏蔽对空fifo的读操作,用full信号屏蔽对满fifo的写操作。这就是“溢出保护”电路。

    4. pointer变化和数据输出和写入的时序关系很关键,如果可能的话,把这两个部分的时序仿真在同一张图里画一下。如果时序很紧张的话,有可能会降低这个fifo的工作频率。

    5. 在verilog语言中的ram描述有可能不能被编译器正确识别出来,是不是把Fitter的报告也粘上来。我认为你这个描述还是很好的。

  • riple

    2007-2-5 14:37:28

    还有一个建议:所有信号都使用“正逻辑”,即“1”表示功能有效,“0”表示功能无效。即使对于复位这样的信号也采用“正逻辑”。建议不要“正”“负”两种逻辑混用,现在看着明白,用起来就可能出错。就像端口参数化一样,“正逻辑”也是为了“傻瓜都用不错”。Altera的lpm宏单元都是用的“正逻辑”。

    刚才说错话了:你用的是VHDL。

  • zhou

    2007-10-24 23:53:45

    你好,
    我现在在初学vhdl,请问你一下那个generic到底有什么用呢?谢谢啦

  • lvchengyatou

    2007-10-30 10:37:14

    站长你好,我是个新手,能不能把用于仿真的testbench文件发给我呀?我的邮箱是hylee1209@126.com,在此先谢过了!!!

  • 2008-3-24 15:30:59

    语法错误太多了

  • 爱晶

    2008-3-25 16:14:20

    好想投你一票,你写的东西真好,但是我不知道怎么投,你能告诉我一下吗?