ruby97的专栏

由于仿真FIFO需要时钟资源,,故使用了前一篇文章中使用的PLL模块。

在仿真FIFO模块时,我使用了一个数据发生模块,参考的下面这篇文章中的源码

datagene.v(可以去链接网址下载源码)

数据发生模块的输入输出框图如下所示:

我在Modelsim中利用了该模块进行FIFO的仿真。若对FIFO的IP核不熟悉,可以参考官方文档:

下面是具体仿真过程:

首先,看一下FIFO配置:

数据单元位宽:16

FIFO最大数据量:512个

读和写使用不同的时钟

OK,下面给出FIFO模块的框图:

找到Quartus中生成的FIFO模块的 verilog文件,把它复制到Modelsim工程中;此外,FIFO仿真还需要的文件是:

所有文件加入工程后如下所示:

其中,write_fifo_module.v代码如下:

module write_fifo_module (wrf_din,clk_100m,clk_20m,sdram_wr_ack,wrf_wrreq,sys_data_in,wrf_use);input[15:0] wrf_din;//data write to FIFOinputclk_100m;//write clockinputclk_20m;//read clockinputwrf_wrreq; //write fifo requestinputsdram_wr_ack; //read fifo requestoutput[15:0] sys_data_in; //read-dataoutput[8:0] wrf_use;//the count of data in fifowrfifouut_wrfifo(.data(wrf_din),.rdclk(clk_20m),.rdreq(sdram_wr_ack),.wrclk(clk_100m),.wrreq(wrf_wrreq),.q(sys_data_in),.wrusedw(wrf_use));endmodule下面是fifo_test_module.v 源码

`timescale 1 ps /1 psmodule fifo_test_module(clk,reset,clk_20m,clk_100m,clk_sdram,system_reset,sdram_rd_ack,sdram_wr_ack,syswr_done,write_fifo_req,write_fifo_data_in,moni_addr,sys_data_in,wrf_use);input clk;input reset;output clk_20m;output clk_100m;output clk_sdram;output system_reset;input sdram_rd_ack;input sdram_wr_ack;output syswr_done;output write_fifo_req;output [15:0]write_fifo_data_in;output [21:0]moni_addr;output [15:0]sys_data_in;output [8:0]wrf_use;sys_ctrluut_sysctrl(.clk(clk),.rst_n(reset),.sys_rst_n(system_reset),.clk_20m(clk_20m),.clk_100m(clk_100m),.sdram_clk(clk_sdram));datageneuut_datagene(.clk_20m(clk_20m),.clk_100m(clk_100m),.rst_n(system_reset),.wrf_din(write_fifo_data_in),.wrf_wrreq(write_fifo_req),.moni_addr(moni_addr),.syswr_done(syswr_done),.sdram_rd_ack(sdram_rd_ack));write_fifo_module uut_write_fifo_module(.wrf_din(write_fifo_data_in),.clk_100m(clk_100m),.clk_20m(clk_20m),.sdram_wr_ack(sdram_wr_ack),.wrf_wrreq(write_fifo_req),.sys_data_in(sys_data_in),.wrf_use(wrf_use));endmodule最后,是测试激励fifo_test_module_tb的代码:

`timescale 1 ps /1 psmodule fifo_test_module_tb;reg clk;reg reset;wire clk_20m;wire clk_100m;wire clk_sdram;wire system_reset;reg sdram_rd_ack;reg sdram_wr_ack;wire syswr_done;wire write_fifo_req;wire [15:0]write_fifo_data_in;wire [21:0]moni_addr;wire [15:0]sys_data_in;wire [8:0]wrf_use;fifo_test_module fifo_test_module_uut(.clk(clk),.reset(reset),.clk_20m(clk_20m),.clk_100m(clk_100m),.clk_sdram(clk_sdram),.system_reset(system_reset),.sdram_rd_ack(sdram_rd_ack),.sdram_wr_ack(sdram_wr_ack),.syswr_done(syswr_done),.write_fifo_req(write_fifo_req),.write_fifo_data_in(write_fifo_data_in),.moni_addr(moni_addr),.sys_data_in(sys_data_in),.wrf_use(wrf_use));initial beginclk = 0;reset=1;sdram_rd_ack=0;sdram_wr_ack=0;#500000000 sdram_rd_ack=1;#1000000 sdram_rd_ack=0; end always #25000 clk = ~clk; always #4000000 sdram_wr_ack=~sdram_wr_ack;endmoduleOK,下面编写ModelSim命令文件: fifo.do

#Creat a work libvlib work #Map the work lib to current libvmap work work #Compile the source filesvlog E:/Project/ModelSim/sdram_test/src/lib/altera_mf.vvlog E:/Project/ModelSim/sdram_test/src/lib/220model.vvlog E:/Project/ModelSim/sdram_test/src/pll/clk_ctrl.vvlog E:/Project/ModelSim/sdram_test/src/pll/sys_ctrl.vvlog E:/Project/ModelSim/sdram_test/src/data_gen/datagene.vvlog E:/Project/ModelSim/sdram_test/src/fifo/wrfifo.vvlog E:/Project/ModelSim/sdram_test/src/fifo/write_fifo_module.vvlog E:/Project/ModelSim/sdram_test/src/fifo/fifo_test_module.vvlog E:/Project/ModelSim/sdram_test/src/fifo_test_module_tb.v #Start simulationvsim -novopt work.fifo_test_module_tb #add waveadd wave -hex /*run 200us下面就可以观察波形了。。:)))

首先,可以看到,在385000ps时,PLL模块初始化完成,可以看到clk_20m,clk_100m,clk_sdram的波形了

系统运行到约100us时,产生了第一次写FIFO请求信号

下面为了观察FIFO的时序,我们把波形放大:

图不是很清晰,只能看清大概,下面具体分析一下:(两个图是连续的,游标位置没有变)

clk_20m:读FIFO时钟

clk_100m:写FIFO时钟(可能会觉得奇怪,为什么读FIFO写到SDRAM的时钟比 写FIFO时钟还慢,确实,原本都是100M,我为了实验,把读时钟改为了20M)

sdram_wr_ack :FIFO读请求信号(这里命名很奇怪。。是因为后面要接SDRAM,写SDRAM即:读FIFO的数据写到SDRAM),高电平有效

write_fifo_req:表示FIFO写请求信号,高电平有效

write_fifo_data_in:写入FIFO的数据(由数据发生器产生)

sys_data_in:FIFO读出的数据

wrf_use:当前FIFO队列里存在的数据个数

没有什么可留恋,只有抑制不住的梦想,

ruby97的专栏

相关文章:

你感兴趣的文章:

标签云: