3580|1

5979

帖子

8

TA的资源

版主

楼主
 

用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代码如下:

[plain] view plaincopy


  • 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 源码

[plain] view plaincopy


  • `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的代码:

[plain] view plaincopy


  • `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

[plain] view plaincopy


  • #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,今天的仿真就到这里吧。。

转载自: http://blog.csdn.net/ruby97/article/details/7348939
此帖出自FPGA/CPLD论坛

最新回复

顶!  详情 回复 发表于 2015-3-31 17:19
点赞 关注
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 

回复
举报

542

帖子

71

TA的资源

纯净的硅(中级)

沙发
 
顶!
此帖出自FPGA/CPLD论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表