用ModelSim仿真FIFO .

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

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

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

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

我在Modelsim中利用了该模块进行FIFO的仿真。若对FIFO的IP核不熟悉,可以参考官方文档:http://www.altera.com/literature/ug/ug_fifo.pdf

下面是具体仿真过程:

首先,看一下FIFO配置:


数据单元位宽:16

FIFO最大数据量:512个

读和写使用不同的时钟





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


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

  • Altera库文件:altera_mf.v ,220_model.v (前一篇有提到这两个文件的位置)
  • 数据发生器文件:datagene.v (参考特权同学的博客,里面可以下载到)
  • PLL模块:sys_ctrl.v clk_ctrl.v前一篇博文有提到
  • FIFO模块:wrfifo.v 
  • 模块封装以及测试文件
所有文件加入工程后如下所示:

其中,write_fifo_module.v代码如下:

  1. module write_fifo_module   
  2. (  
  3.     wrf_din,          
  4.     clk_100m,     
  5.     clk_20m,  
  6.     sdram_wr_ack,  
  7.     wrf_wrreq,    
  8.     sys_data_in,  
  9.     wrf_use  
  10. );  
  11.   
  12.     input   [15:0]   wrf_din;      //data write to FIFO  
  13.     input            clk_100m;     //write clock  
  14.     input          clk_20m;      //read  clock  
  15.     input            wrf_wrreq;    //write fifo request  
  16.     input            sdram_wr_ack; //read fifo request  
  17.     output  [15:0]  sys_data_in;  //read-data  
  18.     output  [8:0]   wrf_use;      //the count of data in fifo  
  19.       
  20. wrfifo          uut_wrfifo(  
  21.                     .data(wrf_din),  
  22.                     .rdclk(clk_20m),  
  23.                     .rdreq(sdram_wr_ack),  
  24.                       
  25.                     .wrclk(clk_100m),  
  26.                     .wrreq(wrf_wrreq),  
  27.                     .q(sys_data_in),  
  28.                     .wrusedw(wrf_use)  
  29.                     );    
  30. endmodule  
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 FIFO
	input	         clk_100m;     //write clock
	input          clk_20m;      //read  clock
	input	         wrf_wrreq;    //write fifo request
	input	         sdram_wr_ack; //read fifo request
	output	[15:0]  sys_data_in;  //read-data
	output	[8:0]   wrf_use;      //the count of data in fifo
	
wrfifo			uut_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 源码

  1. `timescale 1 ps /1 ps  
  2.   
  3. module fifo_test_module(  
  4.     clk,  
  5.     reset,  
  6.     clk_20m,  
  7.     clk_100m,  
  8.     clk_sdram,  
  9.     system_reset,  
  10.     sdram_rd_ack,  
  11.     sdram_wr_ack,  
  12.     syswr_done,  
  13.     write_fifo_req,  
  14.     write_fifo_data_in,  
  15.     moni_addr,  
  16.     sys_data_in,  
  17.     wrf_use  
  18. );  
  19.   
  20. input clk;  
  21. input reset;  
  22.   
  23. output clk_20m;  
  24. output clk_100m;  
  25. output clk_sdram;  
  26. output system_reset;  
  27.   
  28. input sdram_rd_ack;  
  29. input sdram_wr_ack;  
  30.   
  31. output syswr_done;  
  32. output write_fifo_req;  
  33. output [15:0]write_fifo_data_in;  
  34. output [21:0]moni_addr;  
  35. output [15:0]sys_data_in;  
  36. output [8:0]wrf_use;  
  37.   
  38. sys_ctrl        uut_sysctrl(  
  39.                     .clk(clk),  
  40.                     .rst_n(reset),  
  41.                     .sys_rst_n(system_reset),  
  42.                     .clk_20m(clk_20m),  
  43.                     .clk_100m(clk_100m),  
  44.                     .sdram_clk(clk_sdram)  
  45.                     );  
  46.   
  47. datagene            uut_datagene(  
  48.                         .clk_20m(clk_20m),  
  49.                         .clk_100m(clk_100m),  
  50.                         .rst_n(system_reset),  
  51.                         .wrf_din(write_fifo_data_in),  
  52.                         .wrf_wrreq(write_fifo_req),  
  53.                         .moni_addr(moni_addr),  
  54.                         .syswr_done(syswr_done),  
  55.                         .sdram_rd_ack(sdram_rd_ack)  
  56.                     );  
  57.   
  58. write_fifo_module    uut_write_fifo_module(  
  59.              .wrf_din(write_fifo_data_in),        
  60.                .clk_100m(clk_100m),   
  61.                .clk_20m(clk_20m),  
  62.                .sdram_wr_ack(sdram_wr_ack),  
  63.                .wrf_wrreq(write_fifo_req),    
  64.                .sys_data_in(sys_data_in),  
  65.                .wrf_use(wrf_use)                                      
  66.                     );  
  67. endmodule  
`timescale 1 ps /1 ps

module 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_ctrl		uut_sysctrl(
					.clk(clk),
					.rst_n(reset),
					.sys_rst_n(system_reset),
					.clk_20m(clk_20m),
					.clk_100m(clk_100m),
					.sdram_clk(clk_sdram)
					);

datagene			uut_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的代码:

  1. `timescale 1 ps /1 ps  
  2.   
  3. module fifo_test_module_tb;  
  4.   
  5. reg clk;  
  6. reg reset;  
  7.   
  8. wire clk_20m;  
  9. wire clk_100m;  
  10. wire clk_sdram;  
  11. wire system_reset;  
  12.   
  13. reg sdram_rd_ack;  
  14. reg sdram_wr_ack;  
  15.   
  16. wire syswr_done;  
  17. wire write_fifo_req;  
  18. wire [15:0]write_fifo_data_in;  
  19. wire [21:0]moni_addr;  
  20. wire [15:0]sys_data_in;  
  21. wire [8:0]wrf_use;  
  22.   
  23. fifo_test_module fifo_test_module_uut(  
  24.     .clk(clk),  
  25.     .reset(reset),  
  26.     .clk_20m(clk_20m),  
  27.     .clk_100m(clk_100m),  
  28.     .clk_sdram(clk_sdram),  
  29.     .system_reset(system_reset),  
  30.     .sdram_rd_ack(sdram_rd_ack),  
  31.     .sdram_wr_ack(sdram_wr_ack),  
  32.     .syswr_done(syswr_done),  
  33.     .write_fifo_req(write_fifo_req),  
  34.     .write_fifo_data_in(write_fifo_data_in),  
  35.     .moni_addr(moni_addr),  
  36.     .sys_data_in(sys_data_in),  
  37.     .wrf_use(wrf_use)  
  38. );  
  39.   
  40.   
  41.   
  42.  initial  
  43.  begin  
  44.      clk = 0;  
  45.      reset=1;  
  46.      sdram_rd_ack=0;  
  47.      sdram_wr_ack=0;  
  48.      #500000000 sdram_rd_ack=1;  
  49.      #1000000 sdram_rd_ack=0;  
  50.  end  
  51.    
  52.  always #25000 clk = ~clk;  
  53.    
  54.  always #4000000 sdram_wr_ack=~sdram_wr_ack;  
  55.   
  56.   
  57. endmodule  
`timescale 1 ps /1 ps

module 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
 begin
     clk = 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;


endmodule

OK,下面编写ModelSim命令文件: fifo.do

  1. #Creat a work lib  
  2. vlib work   
  3. #Map the work lib to current lib  
  4. vmap work work  
  5.    
  6. #Compile the source files  
  7. vlog E:/Project/ModelSim/sdram_test/src/lib/altera_mf.v  
  8. vlog E:/Project/ModelSim/sdram_test/src/lib/220model.v  
  9. vlog E:/Project/ModelSim/sdram_test/src/pll/clk_ctrl.v  
  10. vlog E:/Project/ModelSim/sdram_test/src/pll/sys_ctrl.v  
  11. vlog E:/Project/ModelSim/sdram_test/src/data_gen/datagene.v  
  12. vlog E:/Project/ModelSim/sdram_test/src/fifo/wrfifo.v  
  13. vlog E:/Project/ModelSim/sdram_test/src/fifo/write_fifo_module.v  
  14. vlog E:/Project/ModelSim/sdram_test/src/fifo/fifo_test_module.v  
  15. vlog E:/Project/ModelSim/sdram_test/src/fifo_test_module_tb.v  
  16.    
  17. #Start simulation  
  18. vsim  -novopt work.fifo_test_module_tb  
  19.    
  20. #add wave  
  21. add wave -hex /*  
  22.   
  23.   
  24.    
  25. run 200us  
#Creat a work lib
vlib work 
#Map the work lib to current lib
vmap work work
 
#Compile the source files
vlog E:/Project/ModelSim/sdram_test/src/lib/altera_mf.v
vlog E:/Project/ModelSim/sdram_test/src/lib/220model.v
vlog E:/Project/ModelSim/sdram_test/src/pll/clk_ctrl.v
vlog E:/Project/ModelSim/sdram_test/src/pll/sys_ctrl.v
vlog E:/Project/ModelSim/sdram_test/src/data_gen/datagene.v
vlog E:/Project/ModelSim/sdram_test/src/fifo/wrfifo.v
vlog E:/Project/ModelSim/sdram_test/src/fifo/write_fifo_module.v
vlog E:/Project/ModelSim/sdram_test/src/fifo/fifo_test_module.v
vlog E:/Project/ModelSim/sdram_test/src/fifo_test_module_tb.v
 
#Start simulation
vsim  -novopt work.fifo_test_module_tb
 
#add wave
add 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队列里存在的数据个数


先看写FIFO的过程,每一个时钟(clk_100m)上升沿,判断写请求信号是否为高电平,如果为高电平,那么就将数据线上的数据写入FIFO,然后在下一个时钟上升沿,wrf_use增加1,表示FIFO队列里的数据增加了一个。

细心的朋友可能会发现,其实在这一过程中,读请求信号一直为高电平,仔细分析这两张图片,大概可以得出如下判断:

在每个读时钟的上升沿,首先判断读请求信号是否为高电平,若为高电平,再判断FIFO是否为空,如果不为空,那么在下一个read_clock的上升沿将数据读出,具体可看下图:


不难发现,第一个read_clock上升沿,FIFO为空;第二个上升沿,FIFO不为空,准备开始读出数据;第三个上升沿,读出数据,同时wrf_use要减1,

而wrf_use是由write_clock维护的,故在下一个写时钟的上升沿,更新wrrf_use (8变成7)。


-------------------------------------------------------------------------------------------------------------------------------------------------------------------

再看一副图,下一个8*16bit 数据,道理还是和上面的一样。



下面看一下读请求为低电平的情况


不难看出,wrf_use随着数据的写入而增加


在累积了一段时间数据后,又迎来了读请求信号,看下图:(还是:上升沿判断,下一个上升沿读取。。。),不再赘述



OK,今天的仿真就到这里吧。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
altera_ug_fifo.pdf audio_dac_fifo.rar FIFO中文应用笔记.pdf FIFO基础知识.doc FPGASoPC软硬件协同设计纵横谈.pdf FPGA的VGA视频输出工程文件// freedev_vga FPGA的VGA视频输出工程文件.rar FreeDev FPGA音频开发环境和平台构建.pdf Nios系统基础上的UItra DMA数据传输模式.doc SD_Card_Audio// Audio_DAC_FIFO_altera的ip核 DE2_SD_Card_Audio sd_audio_aic23.rar SOPC中自定义FIFO接口与DMA数据传输.pdf 什么是FIFO.doc 关于fifo的一些概念其quartus II中IP的使用.doc 在NIOS-II 系统中AD 数据采集接口的设计与实现.doc 基于Avalon总线的TFT LCD 控制器的设计.doc 基于FPGA+PCI的并行计算平台实现 .doc 基于LPM的高速FIFO的设计.doc 基于NiosII的图像采集和显示的实现.doc 基于SOPC的扭振信号测量系统实现研究.doc 基于嵌入式Linux的 TFT LCD IP及驱动的设计.doc 异步FIFO的VHDL设计.doc 采用FPGA的高速数据采集系统.doc 非IP核相关FIFO设计// FIFO技术在SDH数字交叉连接芯片设计中的应用.pdf KPCI-817数据采集卡.pdf PCI-8325光电隔离型模入接口卡技术说明书.doc USB7325高速光电隔离型模入数据采集模块技术说明书.doc 一款低功耗异步FIFO的设计与实现.pdf 一种异步FIFO的设计方法.pdf 关于异步FIFO设计的探讨.pdf 利用FPGA实现异步FIFO设计.doc 基于DSP的高速数据采集与处理系统.pdf 基于FPGA异步FIFO的研究与实现.pdf 基于FPGA的异步FIFO硬件实现.pdf 基于FPGA的异步FIFO设计.pdf 基于FPGA的高速异步FIFO存储器设计.pdf 基于VerilogHDL的异步FIFO设计与实现.pdf 异步FIFO亚稳态问题.doc 异步FIFO结构.pdf 异步FIFO结构及FPGA设计.pdf 怎样对FIFO、RAM读写.doc 读写数据宽度不同的异步FIFO设计.PDF 高速异步FIFO的实现.pdf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值