这篇博客里,通过两个练习来总结在FPGA设计中FIFO读写位宽不同的情况下,我们应该去如何设计时序逻辑,因为在现实工程中FIFO读写位宽不同也是经常出现的情况。

练习1

设计一个模块包含读写位宽是32bit、读写深度是64的异步时钟FIFO,其中输入数据信号din和输入 数据指示信号din_vld是属于clk_in时钟域的,上游模块会负责写数据到本模块的FIFO中,当本模块FIFO写端口已写入了60个数据,也就是FIFO快要写满溢出的时候,这时上游模块仍有数据要写入FIFO则直接丢弃该数据。下游模块负责从本模块的FIFO中读数据,当下游模块输入rdy信号时表示下游模块已准备好可以接收FIFO中的数据了,这时如果FIFO中有数据,那么就把FIFO中的数据赋值给输出数据信号dout送至下游模块并同时拉高dout_vld输出数据指示信号,其中输出数据信号dout和输出数据指示信号dout_vld则是属于clk_out时钟域的,上游模块din信号的写位宽是32bit,下游模块dout信号的读位宽是8bit,表1为练习1的信号列表。

信号列表

信号名

I/O

位宽

clk_in

I

1

rst_n

I

1

rdy

I

1

din

I

32

din_vld

I

1

clk_out

I

1

dout

O

8

dout_vld

O

1

fifo_empty

O

1

表1 FIFO IP练习1设计中的信号列表

我们来思考下练习1功能模块的代码设计,其实不同的地方主要在于上游模块的写位宽din是32bit,而下游模块的读位宽dout是8bit,两者位宽是不一致的,同样的方法我们也在Vivado下初始化一个读写位宽是32bit、读写深度是64的异步时钟FIFO,因为FIFO读写位宽都是32bit,所以上游模块直接写入FIFO即可,这里和练习1中的方法完全一样,但是在读取FIFO的时候,又因为下游模块的读位宽是8bit,而一次性从FIFO中读出的数据是32bit,我们就需要用一个cnt计数器去计数拆分32bit的数据,dout再依次去输出从32bit数据拆分来的数据,同时也拉高dout_vld指示信号,如图1所示FIFO IP练习1的代码设计,具体细节笔者就不再赘述了。

对于FIFO IP练习1的Testbench,其实和FIFO读写位宽相同的设计也大同小异,先模拟上游模块向本模块的写入数据,再模拟输入下游模块准备就绪的rdy信号,这里只补充说明一点,因为FIFO写端口的输入时钟是50Mhz,而读端口的输出时钟是100Mhz,其中上游模块的写位宽din是32bit,下游模块的读位宽dout是8bit,所以给出120个时钟的rdy高电平,大家可以简单计算下,写端口属于clk_in时钟域,120个clk_in应该是120*20ns=2400ns。而读端口属于clk_out时钟域,2400ns就是对应写端口的2400ns/10ns=240个时钟周期,因为下游模块的读位宽是8bit,所以说要输出完32bit*60的数据,需要32bit*60/8bit也就是240个时钟周期,如图2是FIFO IP练习1的输入信号激励设计。

大家打开Vivado环境,添加好功能文件和测试文件后,启动Modelsim进行仿真,如图3是FIFO IP练习1的仿真结果,可以清楚地观察到当fifo_empty为高时,即FIFO当前已经没有数据了,此时恰好dout输出FIFO中的最后一个数据,且dout_vld被拉高,和我们预期的设计效果完全相符。

图1 FIFO IP练习1的代码设计

图2 FIFO IP练习1的输入信号激励设计

图3 FIFO IP练习1的仿真结果

练习2

设计一个模块包含读写位宽是32bit、读写深度是64的异步时钟FIFO,其中输入数据信号din和输入数据指示信号din_vld是属于clk_in时钟域的,上游模块会负责写数据到本模块的FIFO中,当本模块FIFO写端口已写入了60个数据,也就是FIFO快要写满溢出的时候,这时上游模块仍有数据要写入FIFO则直接丢弃该数据。下游模块负责从本模块的FIFO中读数据,当下游模块输入rdy信号时表示下游模块已准备好可以接收FIFO中的数据了,这时如果FIFO中有数据,那么就把FIFO中的数据赋值给输出数据信号dout送至下游模块并同时拉高dout_vld输出数据指示信号,其中输出数据信号dout和输出数据指示信号dout_vld则是属于clk_out时钟域的,上游模块din信号的写位宽是8bit,下游模块dout信号的读位宽是32bit,表2为练习2的信号列表。

信号列表

信号名

I/O

位宽

clk_in

I

1

rst_n

I

1

rdy

I

1

din

I

8

din_vld

I

1

clk_out

I

1

dout

O

32

dout_vld

O

1

fifo_empty

O

1

表2 FIFO IP练习2设计中的信号列表

练习2和练习1一样都是在FIFO相同读写位宽的基础上的延伸扩展,当然Vivado环境下完全支持异步时钟FIFO配置成位宽不同的读写端口,实际工作中也有不少FPGA工程师习惯性去把异步时钟FIFO读写端口根据需求人为配置成位宽不同的,但是笔者还是推荐大家把读写位宽都配置成相同的,这样在程序设计上也更简便不需要再去考虑一些其他因素影响,这里练习1和练习2其实把现实工作中上游模块输入信号din和下游模块输出信号dout的两种可能情况都包括在内了,所以大家实践过这两个练习,在实际项目中完全可以灵活应用,就可以达到二次开发的效果,练习2是输入信号din位宽是32bit,输出信号dout位宽是8bit,所以我们需要对FIFO的输出进行拆分,而练习2相反的是输入信号din位宽是8bit,输出信号dout位宽是32bit,所以我们需要对FIFO的输入进行拼接,练习1和练习2中包含了对数据拼接和拆分的一般性方法,有很强的代表性,如图4所示FIFO IP练习2的代码设计。

对于FIFO IP练习2的Testbench,其实类似练习1,在练习2中因为FIFO写端口的输入时钟是50Mhz,读端口的输出时钟是100Mhz,这里上游模块的写位宽din是8bit,下游模块的读位宽dout是32bit,所以也给出了240个时钟周期的din_vld信号用以模拟上游模块向本模块写入240个8bit的数据,之后再去给出30个clk_in时钟周期的rdy高电平模拟下游模块读数据,这里30个clk_in是30*20ns=600ns,读端口在clk_out时钟域,600ns就对应读端口的600ns/10ns=60个时钟周期,因为下游模块的读位宽是32bit,所以说要输出完32bit*60的数据,需要60个时钟周期,如图5是FIFO IP练习2的输入信号激励设计。如图6 FIFO IP练习2的仿真结果,大家代入Modelsim下可以观察到和预期的设计效果完全一致。

 

图4 FIFO IP练习2的代码设计

图5 FIFO IP练习2的输入信号激励设计

图6 FIFO IP练习2的仿真结果

源工程代码下载链接:

链接:https://pan.baidu.com/s/1XF1unOQV_bYXAzbFoMstKQ 
提取码:g2io

FPGA之FIFO详解,读写位宽不同相关推荐

  1. FPGA之FIFO详解,初识FIFO

    FIFO IP介绍        在篇博客里引入FIFO IP核的概念,FIFO是FPGA中最常用的IP核,经常用在接口模块.串并转换.协议处理.数据缓存等很多场合,所以活学活用这个IP核对于后期项目 ...

  2. 位宽512bit显卡_显卡位宽是什么?详解显卡位宽基础知识科普!

    由于买电脑的时候大家对显卡的显存大小过于重视,很多人忽视了显存位宽的重要性,甚至出现2GB独立显卡但是位宽只有64bit这样坑人的显卡.也许有人说,显卡位宽做大点不就好了么.这是不对的,显卡位宽的扩大 ...

  3. 解决FIFO读写位宽不等的问题

    上周阿里面试官问ram两侧读写位宽不一样改如何解决?当时含糊了一下,事后再认真分析其中缘由. 思路 取读写位宽的最大公因数作为ram的位宽,控制读写指针的步进,并预测下一次的指针位置从而判断空满,和普 ...

  4. 读写位宽不同的FIFO,数据输入输出顺序是怎么样的?BRAM又如何呢?

    原文地址:https://wenku.baidu.com/view/7d7cf156284ac850ac0242b6.html 对于BRAM: 1)写位宽小于读位宽: 先入存低位,后入存高位: 如写4 ...

  5. 面试——异步FIFO详解

    1.异步FIFO简介及其原理 FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序 ...

  6. iTextSharp 使用详解 读写PDF

    iTextSharp 使用详解 PDF文件是目前比较流行的电子文档格式,在办公自动化(OA)等软件的开发中,经常要用到该格式,但介绍如何制作PDF格式文件的资料非常少,在网上搜来搜去,都转贴的是同一段 ...

  7. INF文件详解(32位64位兼容INF)

    INF文件格式要求 一个INF文件是以段组织的简单的文本文件.一些段油系统定义(System-Defined)的名称,而另一些段由INF文件的编写者命名.每个段包含特定的条目和命名,这些命名用于引用I ...

  8. c语言比特和字节,详解 比特(位,bit),字节(Byte),字符的区别 *(转)

    比特(位):英文bit,是计算机晶体管的一种状态(通电与断电).就是0与1,真与假,是计算机最基本的传输单位. 示例: 2bit : 10; 4bit : 1111; 8bit : 1111 1111 ...

  9. 位运算符Java与详解_java位运算符详解

    java位运算符详讲 一.位运算符分类    java中位运算符主要有:按位与&.按位或|.按位非~.按位异或^. 在使用时,需要将运算数都转换为二进制再进行运算,若为负数则使用补码表示.二. ...

最新文章

  1. C# 全选中数字文本框内容
  2. java exec执行tar_用java调用rpmbuild 报错,同一条命令直接复制到终端却能运行
  3. php验证数字100倍数,js如何实现一个文本框只能输入数字 且是100的倍数
  4. 对一个简单汇编程序分析
  5. 弄懂goroutine调度原理
  6. Git的使用——解决中文乱码
  7. AndroidStudio_从Eclipse到AndroidStudio开发工具_两者使用的区别_通过向导新建项目和引入module---Android原生开发工作笔记68
  8. [转]java 输出流转输入流
  9. Centos6.5安装FastDFS
  10. 如何使用Spring Bean Configuration File调用构造方法并给参数赋值
  11. 干支纪年法VB编程:输入一个年份,程序会列出从该年份开始的12年的干支纪年和生肖,希望大神帮我解释期中的关键语句
  12. 区块链技术指南学习笔记1
  13. vi编辑器 末尾添加_linux下的VI编辑器使用手册
  14. Linux之IFS间隔符、C编程、gdb调试
  15. 我的 Input框 不可能这么可爱
  16. uniapp 图片缓存
  17. XXL-JOB研究二 调度中心
  18. i.MX6ULL终结者Linux I2C驱动实验IMX6ULL的I2C总线驱动分析
  19. 网站301跳转问题的探讨和用法,网站做301跳转的相关问题
  20. PostMan测试接口-----上传文件、导出excel

热门文章

  1. Java并发(3)--项目准备:环境初始化、案例准备、并发模拟工具、并发模拟代码
  2. Linux开胃菜:通过xshell对Linux系统的上传下载
  3. 无线倾角报警仪 NB-lot和lora无线倾角仪隧道监测预警
  4. 【数据结构】二叉树(下)
  5. ARP欺骗攻击的检测和防御
  6. 谛听安全如何从5W模式入手,助力内容审核
  7. 类变量,实例变量的区别以及类方法和实例方法的区别
  8. 【已解决】CentOS7等linux系统时区时间不对显示误差8小时
  9. [Qt5控件] 控件stackedWidget、lineEdit等的用法
  10. length()和strlen()