上一篇文章主要讲解了FIFO的一些概念,这篇文章主要讲解VHDL代码。
代码一共有放在7个文件中,其中一个是测试文件,一个package包,一个异步FIFO主模块,一个RAM模块,一个强力同步模块,一个D触发器模块,一个三位的格雷码模块。
注:这个代码使用VHDL-2008,有些EDA可能默认是VHDL-1993,需要在设置中修改一下,否则编译会报错,仿真器modelsim也一样
先从简单的谈起:一个D触发器(vDFF模块),代码如下图:
这个模块是一个非常基础的模块,当时钟上升沿来临时,那么就把D给Q,至于为什么会把这个D触发器作为单独的模块写出来,在Digital Design Using VHDL A Systems Approach 这本书中有这样的描述:在实现所有的时序逻辑时,所有的状态变量都应该被明确的声明为D触发器,不要让VHDL的编译器去推断该用什么触发器。所以在异步FIFO模块中会常调用这个基础模块。提供的代码经过综合后生成如下的原理图:
下面介绍强力同步器(BFSyns模块):这个模块简单来讲就是所谓的两级D触发器(打两拍),是为了减小亚稳态的概率,代码如下:
原理也比较简单,调用两个D触发器即可以实现。下面的图是该代码综合后的原理图
三位格雷编码模块(GrayInc3模块)
这个代码懂得格雷码的编码原理就很好懂,这里不再赘述,不熟悉的读者可以看异步 FIFO(一)这篇文章。下图是代码综合后的原理图
RAM模块(DP_RAM模块)
代码如下
双口RAM用来存储数据
这里来顺带讲一下RAM的基础知识
上图(a)为单口RAM,一次只能由地址a指定一个位置。如果我们在由a指定的位置上进行写操作,就不能同时读取其他位置数据。双口RAM克服了这个限制。双口RAM如图(b)所示,对于双口RAM来说,读端口(信号ao和do)与写端口(信号ai、di和wr)无关。当a0指定某个地址位置的数据通过do输出数据的时候,在同一时间di也可以向由ai指定的地址位置写入数据。下图是上述的双口RAM代码综合出来的原理图。
异步FIFO主模块代码
这些代码都是整合以上子模块,以及添加一些控制流,如果有不明白可以看异步FIFO(一)文章,在获得代码后可以综合后看看原理图,这样更好理解
关于主模块我就不详细讲解,关于一些逻辑的控制流在第一篇有讲。
仿真结果
总结:两篇文章,大概讲了异步FIFO,以后也许还会进行补充,顺便讲一下后面的计划:VHDL的语法重新整理、IIC、QSPI控制器、ADC、其它的一些基础模块(状态机、ROM、RAM)、包含一些小的项目。基础模块计划比较多,项目模块还在准备中。
没有回复内容