• IP核——FIFO


    一、Quartus

    1.打开Quartus ii,点击Tools---MegaWizard Plug-In Manager

    2.弹出创建页面,选择Creat a new custom megafunction variation,点Next

    3.选择IP核,可以直接搜索fifo,选择fifo,右上方选择器件型号,语言选成Verilog,再填写一下路径名字,点Next,后面就是参数设置了。

    4.设置数据的宽度和深度,宽度即数据位宽,深度即fifo里做多存放多少个数据,深度的计算要考虑写的时刻和读的时刻以及时钟快慢。下面是选中同步时钟还是异步时钟,这里选择同步时钟,下面的设置也是基于同步时钟。如果是异步时钟则下面的设置会出现写侧和读侧两对参数进行选择,其实是一样的道理。Next

    4.选择一些指示信号,需要就选,不需要就不选,Next

    5.选择哪种模式,这还是有些学问的,图上用文字简单的说明了一下,下面做个实验来看看他们究竟有什么不同。存储类型选择默认的Auto就行。Next

    6.默认,Next

    7.默认,Next

    8.一般不勾选bb文件,finish。

     

     二、ISE

    1.创建ISE工程,IP核需要在ISE工程里面进行调用。点击Tools---Core Generator...

    2.在新弹出来的界面中创建一个属于IP核的工程:file---new project,并填写文件存储位置和文件名称,一般为ipcore_dir文件夹,点击保存

    3.弹出的Part处填写器件的系列、型号、封装以及速度等级,Generation处设置语言为Verilog,点击OK

    4.点击文件夹,找到Memories & Storage Elements---FIFOs---FIFO Generator,(也可以直接搜索fifo)双击打开,进行参数设置

    5.命名,类型选择默认即可,Next

     6.选择同步或异步,一般是选中含有Block RAM的选项,Next

    .

    7.模式选择和宽度、深度选择。Next

     8.信号选择,需要就勾选,不需要就不勾选,Next

    9.是否进行初始化,Next

    10.是否进行数据计数,Next

    11.总结页面,Generate

    三、Normal(Standard)模式和Show-ahead(First-word fall-through)模式的区别

      对此很多书籍没有多提及,教学视频也就一两句话带过。我一直似懂非懂,于是编了个仿真来测试一下。

    1.设计文件

      我例化了两个fifo,一个Normal模式的fifo,一个Show-ahead模式的fifo,他们的写数据、写使能、读使能都一样,用控制变量法观察q的输出情况。这段代码意思很简单,我设计了一个0-21的输入数据和对应输入有效指示信号。将数据为123456789 10时,这些数据写入fifo。在数据等于11 12 13 14 15 16 17 18 19 20时,将刚刚写入fifo的数据读出来。后面又加入一个dout输出,测试rdreq做if条件,后面会出现什么有趣结果。

     1 //==========================================================================
     2 // --- 名称 : fifo_ctrl.v
     3 // --- 作者 : xianyu_FPGA
     4 // --- 日期 : 2019-01-03
     5 // --- 描述 : 数据进来,写满就开始读。normal模式和show_ahead模式对比
     6 //==========================================================================
     7 
     8 module fifo_ctrl
     9 //---------------------<端口声明>-------------------------------------------
    10 (
    11 input  wire             clk                 , //时钟,50Mhz
    12 input  wire             rst_n               , //复位,低电平有效
    13 input  wire [7:0]       din                 , //输入数据
    14 input  wire             din_vld             , //输入数据指示信号
    15 output reg  [7:0]       dout_normal         ,
    16 output reg  [7:0]       dout_show_ahead
    17 );
    18 //---------------------<信号定义>-------------------------------------------
    19 wire [7:0]              data                ; //fifo输入的数据
    20 wire                    rdreq               ; //fifo读请求
    21 wire                    wrreq               ; //fifo写请求
    22 wire [7:0]              q_normal            ; //fifo输出的数据
    23 wire [7:0]              q_show_ahead        ; //fifo输出的数据
    24 
    25 //--------------------------------------------------------------------------
    26 //--   FIFO例化
    27 //--------------------------------------------------------------------------
    28 ip_fifo_normal u_1
    29 (
    30     .clock              (clk                ),
    31     .data               (data               ),
    32     .rdreq              (rdreq              ),
    33     .wrreq              (wrreq              ),
    34     .empty              (                   ),
    35     .full               (                   ),
    36     .usedw              (                   ),
    37     .q                  (q_normal           )
    38 );
    39 
    40 ip_fifo_show_ahead u_2
    41 (
    42     .clock              (clk                ),
    43     .data               (data               ),
    44     .rdreq              (rdreq              ),
    45     .wrreq              (wrreq              ),
    46     .empty              (                   ),
    47     .full               (                   ),
    48     .usedw              (                   ),
    49     .q                  (q_show_ahead       )
    50 );
    51 
    52 //--------------------------------------------------------------------------
    53 //--   fifo 写
    54 //--------------------------------------------------------------------------
    55 assign data  = din;
    56 assign wrreq = din_vld && din>=1 && din<=10; //写进123456789 10
    57 
    58 
    59 //--------------------------------------------------------------------------
    60 //--   fifo 读
    61 //--------------------------------------------------------------------------
    62 assign rdreq = din_vld && din>=11; //第11个数后开始读
    63 
    64 
    65 //--------------------------------------------------------------------------
    66 //--   输出
    67 //--------------------------------------------------------------------------
    68 always @(posedge clk or negedge rst_n) begin
    69     if(!rst_n) begin
    70         dout_normal     <= 0;
    71         dout_show_ahead <= 0;
    72     end
    73     else if(rdreq) begin
    74         dout_normal     <= q_normal;
    75         dout_show_ahead <= q_show_ahead;
    76     end
    77 end
    78 
    79 
    80 
    81 
    82 endmodule

    2.测试文件

      输入数据和对应指示信号,数据为:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

     1 `timescale 1ns/1ps  //时间精度
     2 `define    Clock 20 //时钟周期
     3 
     4 module fifo_ctrl_tb;
     5 
     6 //---------------------<端口定义>-------------------------------------------
     7 reg                     clk                 ; //时钟,50Mhz
     8 reg                     rst_n               ; //复位,低电平有效
     9 reg  [7:0]              din                 ; //输入数据
    10 reg                     din_vld             ; //输入数据指示信号
    11 wire [7:0]              dout_normal         ;
    12 wire [7:0]              dout_show_ahead     ;
    13 
    14 //--------------------------------------------------------------------------
    15 //--   模块例化
    16 //--------------------------------------------------------------------------
    17 fifo_ctrl u_fifo_ctrl
    18 (
    19     .clk                (clk                ),     
    20     .rst_n              (rst_n              ),
    21     .din                (din                ),
    22     .din_vld            (din_vld            ),
    23     .dout_normal        (dout_normal        ),
    24     .dout_show_ahead    (dout_show_ahead    )
    25 );
    26 
    27 //----------------------------------------------------------------------
    28 //--   时钟信号和复位信号
    29 //----------------------------------------------------------------------
    30 initial begin
    31     clk = 1;
    32     forever
    33         #(`Clock/2) clk = ~clk;
    34 end
    35 
    36 initial begin
    37     rst_n = 0; #(`Clock*20+1);
    38     rst_n = 1;
    39 end
    40 
    41 //----------------------------------------------------------------------
    42 //--   设计输入信号
    43 //----------------------------------------------------------------------
    44 reg     [4:0]    i;
    45 
    46 task data;
    47     begin
    48         for(i=0;i<=20;i=i+1) begin
    49             din     = i;
    50             din_vld = 1;
    51             #(`Clock);
    52             din_vld = 0;
    53             #(`Clock*4);
    54         end
    55     end
    56 endtask
    57 
    58 
    59 initial begin
    60     #1;
    61     din     = 0;
    62     din_vld = 0;
    63     #(`Clock*20+1); //初始化完成
    64     
    65     data;
    66     #(`Clock*5);
    67     $stop;
    68 end
    69 
    70 
    71 
    72 endmodule

    3.仿真波形

      波形中出现了多个rdreq信号,其实是同一个,为了方便看情况,我进行了复制信号而且改了颜色罢了。图中信号,绿色为输入信号,红色为fifo写信号,黄色为normal模式的情况,紫色为show-ahead模式的情况。

     

    4.结论

      ①Normal:先有rdreq,q中再有数据。输出不能用rdreq做if判断,否则会丢数据,如果一定要用到rdreq搞事情,那么rdreq打一拍再用就行了。

      ②Show-ahead:q上一直有数据,有rdreq就切换到下一个数据,rdreq信号像是应答信号ack。输出可以直接用rdreq做if判断。

    四、ROM、RAM和FIFO的区别

    1.ROM有地址,只能读而不能写。用初始化文件mif/ceo将内容存进去,读取不会使得数据减少消失。

    2.RAM有地址,可以进行寻址读写,数据写进去后,读取不会使得数据减少消失。

    3.FIFO没有地址,只能是先进先出,数据写进去后,读取会使得数据减少消失,读一个少一个。

    参考资料:

    [1]小梅哥FPGA教程

    [2]威三学院FPGA教程

  • 相关阅读:
    python之路(三)-深浅拷贝
    Python之路(一)-python简介
    Web端裁剪图片方法
    如何将github上源代码导入eclipse中
    转 GitHub上史上最全的Android开源项目分类汇总
    转 GitHub上最火的40个Android开源项目(二)
    转 GitHub上最火的40个Android开源项目(一)
    转 GitHub上最火的74个Android开源项目(三)
    CSS实现文本溢出的部分用省略号代替的方法
    时尚且健壮: 实现更优秀的CSS
  • 原文地址:https://www.cnblogs.com/xianyufpga/p/11128790.html
Copyright © 2020-2023  润新知