0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA零基础学习之Vivado-FIFO使用教程

FPGA技术江湖 来源:FPGA技术江湖 2023-06-09 09:38 次阅读

FIFO使用教程

作者:李西锐校对:陆辉

FIFO的英文全称叫做First in First out,即先进先出。这也就决定了这个IP核的特殊性,先写进去的数据优先被读出,所以,FIFO是不需要地址信号线的,这也是它的一大特点,通常用来做数据的缓存,或者用来解决高速异步数据的交互,即解决了跨时钟域的问题。此外,FIFO还有一个特点,就是数据被读出之后就不存在了,不像RAMROM一样,数据被读出后还存在。所以我们如果想进行多次的读,那么就需要进行同样次数的写。

FIFO分为同步时钟和异步时钟,同步FIFO指的是读写使用同一个时钟,在时钟沿信号来的时候进行读写。异步FIFO是指读写在不同时钟下进行,这样我们可以实现读写不同速度。

那么接下来,我们就来实现一下异步FIFO的读写过程。

2691bb5c-05ea-11ee-962d-dac502259ad0.png

上图为选择异步FIFO之后的图示,在这个图示中,我们给大家解释一下每个信号的含义。

FIFO_WRITE

full:FIFO的满信号,当FIFO的存储空间写满了之后,此信号拉高,否则为低。此信号为FIFO的输出信号。

din[17:0]:FIFO的数据输入,写进FIFO的数据通过此信号线进入FIFO。

wr_en:FIFO的写使能,当我们要往FIFO里面写入数据时,拉高此信号。此信号为FIFO的输入。

FIFO_READ

empty:FIFO的空信号,当FIFO的存储空间空了之后,此信号拉高,否则为低。此信号为FIFO的输出信号。

dout:FIFO的数据输出,读出FIFO的数据通过此信号线输出。

rd_en:FIFO的读使能,当我们要从FIFO里面读出数据时,拉高此信号。此信号为FIFO的输入。

rst:FIFO复位,默认高电平有效。

wr_clk:写时钟

rd_clk: 读时钟

wr_rst_busy:写复位忙信号

rd_rst_busy:读复位忙信号

在了解了FIFO的端口之后,我们来实现一个应用实例。比如,我们以10MHz的速度往FIFO里面写数据,写满之后,在20MHz的时钟下将数据读出,一直读空。当然,在显示应用中,FIFO的读写是可以同步进行的。

首先,我们先来新建工程。

新建好之后,我们先调用一下IP核:

2699dc38-05ea-11ee-962d-dac502259ad0.png

在IP核管理器界面,搜索FIFO,然后选中图示所选项双击打开。

26adbbea-05ea-11ee-962d-dac502259ad0.png

在FIFO类型选项,我们选择异步FIFO。刚打开默认的选项为同步FIFO。

26be877c-05ea-11ee-962d-dac502259ad0.png

在数据端口配置界面,我们将数据位宽改为8bit,深度使用1024。

复位端口在这就不再使用了,所以勾选位置取消掉。

26ce6354-05ea-11ee-962d-dac502259ad0.png

在此界面出现了almost full flag和almost empty flag。这两个信号是几乎满或空的标志信号,在此实验中,我们不使用。

26de3c16-05ea-11ee-962d-dac502259ad0.png

Datacount是FIFO数据用量计数器,代表了此时FIFO的内部存储被使用的情况。假设我们写进去了10个数,那么两个计数器都为10。

26f6b30e-05ea-11ee-962d-dac502259ad0.png

此界面为IP核的信息,在此界面可以看出,我们的读写深度发生了变化,我们在前面设置的深度为1024,但是在此处显示的却是1023。原因是因为FIFO结构的特殊性,并不是我们设置的有问题。所以,在我们这个异步FIFO中,深度为1023。

27085a64-05ea-11ee-962d-dac502259ad0.png

点击OK直接生成。在点击Generate。

此外,我们还需要两个不同时钟,在这里我们使用锁相环生成。

2719ba5c-05ea-11ee-962d-dac502259ad0.png

在管理界面搜索clock。配置过程我们在此前已经讲过,就不在过多叙述。

接下来我们写一下fifo的写控制器,代码如下:

1   module fifo_wr(
2     
3     input   wire             clk,
4     input   wire             rst_n,
5     input   wire             empty,
6     input   wire             full,
7     output   reg             fifo_wr_en,
8     output   reg     [7:0]      fifo_data_in
9   );
10
11    reg         state;
12    
13    always @ (posedge clk, negedge rst_n)
14    begin
15      if(rst_n == 1'b0)
16        begin
17          fifo_wr_en <= 1'b0;
18          fifo_data_in <= 8'd0;
19          state <= 1'b0;
20        end
21      else
22        case(state)
23          1'b0  :  begin
24                  if(empty)
25                    state <= 1'b1;
26                  else
27                    state <= 1'b0;
28                end
29          1'b1  :  begin
30                  if(full)
31                    begin
32                      fifo_wr_en <= 1'b0;
33                      fifo_data_in <= 8'd0;
34                      state <= 1'b0;
35                    end
36                  else
37                    begin
38                      fifo_wr_en <= 1'b1;
39                      fifo_data_in <= fifo_data_in + 1'b1;
40                      state <= 1'b1;
41                    end
42                end
43        endcase
44    end
45
46  endmodule

因为我们的实验是读空了才写,所以我们用状态机来做,先判断FIFO是否为空。读控制器代码如下:

1   module fifo_rd(
2     
3     input   wire               clk,
4     input   wire               rst_n,
5     input   wire               empty,
6     input   wire               full,
7     output   reg               fifo_rd_en
8   );
9 
10    reg         state;
11    
12    always @ (posedge clk, negedge rst_n)
13    begin
14      if(rst_n == 1'b0)
15        begin
16          fifo_rd_en <= 1'b0;
17          state <= 1'b0;
18        end
19      else
20        case(state)
21          1'b0  :  begin
22                  if(full)
23                    state <= 1'b1;
24                  else
25                    state <= 1'b0;
26                end
27          1'b1  :  begin
28                  if(empty)
29                    begin
30                      fifo_rd_en <= 1'b0;
31                      state <= 1'b0;
32                    end
33                  else
34                    begin
35                      fifo_rd_en <= 1'b1;
36                      state <= 1'b1;
37                    end
38                end
39        endcase
40    end
41
42  endmodule

顶层代码如下:

1   module fifo(
2     
3     input   wire               clk,
4     input   wire               rst_n,
5     output   wire       [7:0]      q
6   );
7     
8     wire           fifo_wr_clk;
9     wire           fifo_rd_clk;
10    wire           locked;
11    wire           empty;
12    wire           full;
13    wire           fifo_wr_en;
14    wire     [7:0]    fifo_data_in;
15    wire           fifo_rd_en;
16    
17    clk_wiz_0 clk_wiz_0_inst
18     (
19    // Clock out ports
20    .clk_out1(fifo_wr_clk),     // output clk_out1
21    .clk_out2(fifo_rd_clk),     // output clk_out2
22    // Status and control signals
23    .reset(~rst_n), // input reset
24    .locked(locked),       // output locked
25     // Clock in ports
26    .clk_in1(clk));      // input clk_in1
27    
28    fifo_wr fifo_wr_inst(
29    
30    .clk            (fifo_wr_clk),
31    .rst_n            (locked  ),
32    .empty            (empty    ),
33    .full            (full    ),
34    .fifo_wr_en          (fifo_wr_en  ),
35    .fifo_data_in        (fifo_data_in)
36  );
37
38    fifo_generator_0 fifo_generator_0_inst (
39      .wr_clk(fifo_wr_clk),  // input wire wr_clk
40      .rd_clk(fifo_rd_clk),  // input wire rd_clk
41      .din(fifo_data_in),        // input wire [7 : 0] din
42      .wr_en(fifo_wr_en),    // input wire wr_en
43      .rd_en(fifo_rd_en),    // input wire rd_en
44      .dout(q),      // output wire [7 : 0] dout
45      .full(full),      // output wire full
46      .empty(empty)    // output wire empty
47    );
48
49    fifo_rd fifo_rd_inst(
50    
51    .clk        (fifo_rd_clk),
52    .rst_n        (locked    ),
53    .empty        (empty    ),
54    .full        (full    ),
55    .fifo_rd_en      (fifo_rd_en)
56  );
57    
58  endmodule

代码写完之后,我们写个仿真验证一下波形,代码如下:

1   `timescale 1ns / 1ps
2 
3   module fifo_tb;
4 
5     reg                clk;
6     reg                rst_n;
7     wire       [7:0]      q;
8     
9     initial begin
10      clk = 0;
11      rst_n = 0;
12      #105;
13      rst_n = 1;
14      #10000;
15      $stop;
16    end
17    
18    always #10 clk = ~clk;
19    
20    fifo fifo_inst(
21    
22    .clk      (clk),
23    .rst_n      (rst_n),
24    .q        (q)
25  );
26
27  endmodule

打开波形之后,我们将读写控制模块的信号全部添加到波形窗口:

272c2aca-05ea-11ee-962d-dac502259ad0.png

添加好之后,点击restart和run-all

273a6162-05ea-11ee-962d-dac502259ad0.png

由于波形默认运行10us,我们观察不到全部波形,所以,在此我们继续点击run-all,然后点击break,让仿真停止。

27478004-05ea-11ee-962d-dac502259ad0.png

然后,我们观察波形:

2752821a-05ea-11ee-962d-dac502259ad0.png

在波形里面可以清楚的看到我们的fifo_data_in和q的波形,一长一短。这是因为读的速度快,所以波形维持的时间短。写数据的时间长度是读数据时间长度的两倍。

然后放大波形观察其他信号:

276173ec-05ea-11ee-962d-dac502259ad0.png

在黄色光标位置,可以看到满信号拉高了,然后写使能就拉低了,状态开始进入到读。在读使能拉高之后,输出q就有了数据,但是我们的empty信号维持了一段时间才拉低,这是因为fifo的特殊结构导致的,在此我们就不再过多讨论。

结论:异步FIFO控制正确,仿真波形输入和输出信号正常。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1602

    文章

    21324

    浏览量

    593216
  • fifo
    +关注

    关注

    3

    文章

    369

    浏览量

    43069
  • 时钟
    +关注

    关注

    10

    文章

    1479

    浏览量

    130306
  • IP核
    +关注

    关注

    4

    文章

    317

    浏览量

    49043
  • Vivado
    +关注

    关注

    18

    文章

    790

    浏览量

    65102

原文标题:FPGA零基础学习之Vivado-FIFO使用教程

文章出处:【微信号:HXSLH1010101010,微信公众号:FPGA技术江湖】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    ARM入门,零基学习

    ARM入门,零基学习。自学过,觉得非常好。分享一下。
    发表于 03-24 16:31

    FPGA高手的养成记:零基础学FPGA 连载—小墨同学出品

    ://bbs.elecfans.com/jishu_475405_1_1.html零基础学FPGA(十二)基于FIFO的串口发送机设计全流程https://bbs.elecfans.com
    发表于 04-03 11:22

    怎样从开始学习fpga

    我是听别人说fpga的,而且还听说是硬件工程师必会的技能,我的理想就是成为工程师,但是我以前都没有接触过fpga,可以说是零基础。所以跪求大神介绍学习方法,应该买什么
    发表于 08-17 12:41

    关于“小墨同学”推出的零基FPGA“基于FIFO的串口发送机设计全流程”相关部分讨论

    链接为“小墨同学”推出的零基FPGA“基于FIFO的串口发送机设计全流程”,https://bbs.elecfans.com/jishu_475408_1_1.html其中,有几个部分不是很明白小墨同学的设计思路,希望大家拍砖
    发表于 07-27 19:34

    零基础入门FPGA,如何学习?精选资料分享

    问:本人零基础,想学FPGA,求有经验的人说说,我应该从哪入手,应该看什么教程,应该用什么学习板和开发板,看什么书等,希望有经验的好心人能够给我一些引导。如果想速成,那就上网看视频吧,这...
    发表于 07-20 07:28

    零基础如何学习stm32?

    零基础如何学习stm32?
    发表于 12-21 07:53

    FPGA零基学习:LED流水灯设计

    前篇中已经明确罗列,以后将不再叙述。这里给出超链接,方便参考学习FPGA零基学习:Intel FPGA 开发流程 · 设计代码 para
    发表于 03-07 16:39

    FPGA零基学习:IP CORE ROM设计

    CORE ROM设计 本篇实现基于叁芯智能科技的SANXIN -B01 FPGA开发板,以下为配套的教程,如有入手开发板,可以登录官方淘宝店购买,还有配套的学习视频。 SANXIN-B01
    发表于 03-13 15:46

    FPGA零基学习:IP CORE FIFO设计

    CORE FIFO设计 本篇实现基于叁芯智能科技的SANXIN -B01 FPGA开发板,以下为配套的教程,如有入手开发板,可以登录官方淘宝店购买,还有配套的学习视频。 SA
    发表于 03-15 16:19

    FPGA零基学习:SDR SDRAM驱动设计实用进阶

    大侠好,欢迎来到FPGA技术江湖。本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白
    发表于 03-27 17:09

    FPGA零基学习Vivado-LED流水灯实验

    及打算进阶提升的职业开发者都可以有系统性学习的机会。系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。本次带来Vivado系列,本篇为FPGA零基
    发表于 04-18 21:12

    FPGA零基学习Vivado-数码管驱动设计实验

    不多说,上货。FPGA零基学习Vivado-数码管驱动设计实验数码管作为SANXIN-B04的显示装置,具有易控制,显示方便的特点。那么
    发表于 04-19 19:21

    FPGA零基学习Vivado-按键使用教程

    大侠好,欢迎来到FPGA技术江湖。本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白
    发表于 06-13 18:33

    FPGA零基学习Vivado-FIFO使用教程

    及打算进阶提升的职业开发者都可以有系统性学习的机会。 系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。本次带来Vivado系列,FIFO使用教程。话不多
    发表于 06-16 17:50

    FPGA零基学习Vivado-TLC549驱动设计

    大侠好,欢迎来到FPGA技术江湖。本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白
    发表于 08-16 19:57