在参加集创赛过程中,发现国产的FPGA的资料文件非常稀缺,很多东西废了千辛万苦自己把代码手撕出来,为了以防自己会忘了,决定记录下一些自认为比较重要的东西,也方便后来人可以查看。
模块输入输出
这里的输入是16位的数字音频信号,当且仅当i_en有效时候,因此后续需要逻辑块(always)对其赋值,输入配置如下:
- 输入时钟信号
- 输入系统复位信号(0有效)
- 输入音频信号有效信号(这个自行更改)
- 输入音频信号16位
- 读出乒乓操作后的数据
状态机
- IDLE:初始状态,在不工作或复位时就让状态机置为初始状态。
- WRAM1:写RAM1状态。该状态我们开始往RAM1中写入数据,此时由于RAM2中并没有写入数据,所以我们不用对RAM2进行读取。
- WRAM2_RRAM1:写RAM2读RAM1状态,当第一包数据写入完毕之后,马上跳到该状态,将第二包数据写入到RAM2中的同时读出RAM1中的写入的第一包数据。
- WRAM1_RRAM2:写RAM1读RAM2状态。在该状态下我们开始向RAM1中写入第三包数据,此时第三包数据会把第一包数据覆盖,而我们的第一包数据已经读取出来了,并不会使数据丢失。在往RAM1中写入第三包数据的同时,我们读出RAM2中的第二包数据,当读写完成之后,跳回WRAM2_RRAM1状态开始 下一包的数据写入以及读取,如此循环我们就能无缝地将连续的输入数据读取出来了。
1 | //状态跳转 |
计数器
wea和web是ram的使能,有的ram有读使能和写使能,这里做了简化,使能为1就写,使能为0就读。
1 | //组合逻辑 |
上述代码搭配计数器就可以实现一半时序为读使能一半时序为写使能。
1 | //读写状态计数器 |
RAM配置
既然是乒乓操作,必然需要两片空间可以交换读取的,这里选取了RAM,配置如下:
- 写数据16位(即[15:0])
- 地址9位(即[8:0])
- 输入时钟信号i_clk
- 启动信号wea or web(这里配置为!rst,即不复位有效,rst是0的时候系统复位)
- 读数据信号16位(即[15:0])
整体实现代码
1 | module ram_in_out( |
(新手第一次写博客,如有错误和不好的地方,请多担待,另外对程序有问题请提出噢!)