本帖最后由 梦翼师兄 于 2015-7-20 13:06 编辑
前言:移位寄存器的IP核貌似一直不太起眼,很多初学者都不知道,现在我们就来关心一下这个怀才不遇的IP核。
一、原理 相信大家通过前几章的学习,应该已经对FPGA 有了一定的了解,现在我们来探讨这样一个问题,假设数据在一个ROM中以如下图所示(图1)的方式存放,列加行的值作为该数的地址(如e的地址就是8+1=9)。 图1 在图像处理领域,要使用Sobel算法或者均值处理等方式来实现,而取数据时要取出一个3 的矩阵数据,如下图所示:(现在想要每次取出3列数据为一组,如第一列数据:a、b、c 第二列数据:d、e、f 第三列数据:g、h、i)
于是,问题来了:怎样在图一的RAM中取出如图2所示的数据呢?在这儿我想给大家介绍一个叫做Shift_register的 IP核来实现这种功能,而且还有很重要的一点就是我们可以利用这种方法来实现流水线操作,我们暂且就将其看做是移位寄存的“FIFO”吧。 如果我们将该IP核配置成如下图所示的两个“FIFO”,那么我们从ROM中取数的原理就可以用下图表示:
(1) 有两个“FIFO”,长度都是8。ROM中的数据从in端口输入,每次地址加一。 (2) 用一个计数器cnt作为ROM的地址线,cnt每增加1,ROM就会输出新的数据并通过in[7:0]端口进入shift_register,同时shift_register中的所有数据就会同步向前移位一次,等计数到16时结果如下:
(3)下一个时钟到来时候开始同时取值shiftout0、shiftout1、shiftout2
二、架构图如下图所示:
三、程序部分:3.1顶层top.v
3.2ROM在以前的教程ROM之战中已经学过了mif文件与ROM的IP核使用,这些都不再赘述了。现在我们做一个位宽是8bit,深度是256的单口ROM,命名为my_rom,并且让使my.mif文件(1~255、0)作为my_rom的初始文件。如下图所示 值得一提的是在ROM之战的第10页和第11页中
q前的对勾去掉(打钩的区别大家可以通过仿真图看观察,实际上会造成一拍潜伏期,即:结果会晚一个时钟出现)
[url=]3.3countercomunter的代码如下:功能是产生ROM的地址和最终输出的使能信号
3.14调用移位寄存器的IP核
(1)打开IP核选择如下的选项,并命名为my_register,点击下一步。
(2) 具体参数做如下设置。Number of taps 为2表示将有两个“FIFO”被例化出来作为移位寄存,Tap distance为8表示每个FIFO的深度为8(即每个FIFO可以存放8个数据)。“shiftin”and“shiftout”width 为8bit表示数据的位宽是8位。
(3)一直点击下一步,直到完成。 3.5shift_register
功能实现:在使能有效的时候输出有效的数据。 3.7top
最终top.v文件如下图: 3.7测试文件top_tb
3.8仿真
仿真波形: 由mif文件可知ROM中的初始值是1.23.4.5.6.7…..,由波形图可以看出在使能有效的时候输出如下图所示的3*3阵列
|