zoukankan      html  css  js  c++  java
  • [转] 用ModelSim仿真PLL模块

    由于要对FPGA读写SDRAM的工程进行调试,第一步就是验证PLL模块的功能,故结合网上找的一些资料,进行了如下PLL仿真实验。

    下面是仿真的全过程

    • 首先,看一下Quartus中的PLL模块:

    从上面图中可以看出:我的FPGA输入时钟是20MHZ,该PLL有三个输出,其中

    C0:5倍频,100MHZ

    C1:1倍频,20MHZ

    C2:5倍频,100MHZ,同时相对于C0延时2ns,也就是72度的相位差。

    • 下面,新建一个Modelsim的工程。然后在工程目录下新建两个文件夹,分别为src以及modelsim,如图所示
    • 下面,给工程添加库文件,源文件以及激励文件:
    首先,添加库文件,在quartus目录下(E:\Altera\quartus\eda\sim_lib),即sim_lib文件夹中复制两个库文件:
    altera_mf.v 和 220model.v,把它们复制到src目录下
     
    然后,找到Quartus工程中生成的pll模块的文件,我的是clk_ctrl.v(第一幅图可以看出),把它复制到src目录下;
     
    然后新建一个pll_module.v文件,对PLL模块进行一次小包装,代码如下:
     
    `timescale 1 ps / 1 ps
    
    module pll_module(
    clk,
    reset,
    clk_20m,
    clk_100m,
    sdram_clk,
    sys_reset
    );
    
    input clk;
    input reset;
    output clk_20m;
    output clk_100m;
    output sdram_clk;
    output sys_reset;
    
    
    
    clk_ctrl clk_ctrl_u1 (
    .areset(reset),
    .inclk0(clk),
    .c0(clk_20m),
    .c1(clk_100m),
    .c2(sdram_clk),
    .locked(sys_reset)
    );
    
    endmodule
     
    接下来,编写testbench文件,pll_module_tb.v
    <span style="font-size: 13px; "><span style="font-family:'Microsoft YaHei';">`timescale 1 ps / 1 ps  
    module pll_module_tb;  
      
    reg     clk;  
    reg      reset;  
    wire    clk_100m;  
    wire    clk_20m;  
    wire    sdram_clk;  
    wire    sys_reset;  
      
    pll_module    u1(  
         .clk(clk),  
         .reset(reset),  
         .clk_20m(clk_20m),  
         .clk_100m(clk_100m),  
         .sdram_clk(sdram_clk),  
         .sys_reset(sys_reset)  
         );  
       
     initial  
     begin  
         clk = 0;  
         reset=0;  
     end  
       
     always #25000 clk = ~clk;  
       
      
     endmodule</span></span> 

    由于仿真以ps为单位,而FPGA的输入时钟为20MHZ,即每周期50ns=50000ps,所以上面代码中的clk每25000个仿真时间进行一次翻转。

     
     
    完成后的src目录下现在应该有5个文件:
     
    • 下面,我们可以开始准备仿真了。通常我们都是先编译,然后在添加波形文件,然后run xxxxxx ;这样比较繁琐,其实用命令往往比较方便快捷。
    在工程的modelsim目录下新建文件pll.do,并写入如下代码
    <span style="font-size: 13px; "><span style="font-family:'Microsoft YaHei';">#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/altera_mf.v  
    vlog E:/Project/ModelSim/sdram_test/src/220model.v  
    vlog E:/Project/ModelSim/sdram_test/src/clk_ctrl.v  
    vlog E:/Project/ModelSim/sdram_test/src/pll_module.v  
    vlog E:/Project/ModelSim/sdram_test/src/pll_module_tb.v  
       
    #Start simulation  
    vsim  -novopt work.pll_module_tb  
       
    #add wave  
    add wave -hex /*  
       
    run 500000000</span></span>  
    上面这段代码完成了以下事情:
    1.建立了一个工作lib
    2.使该lib成为当前lib
    3.编译工程中的文件
    4.开始仿真,其中 -novopt是禁止优化的意思
    5.添加波形文件
    6.仿真 500000000个时间单位
     
    • 现在,整个modelsim工程的文件结构如下:

    下面,右键点击pll.do,选择execute就可以执行该脚本了。modelsim会自动帮您把所有事情搞定。(这一过程时间比较长,请耐心等待一会),结果如下图:

    不难看出,从波形上看,是满足预先的设想的。下面可以放大来看一下

    从放大的图片可以看出,两个100m的时钟之间确实存在相位差,换算成时间约为2ns,这也就验证了我的PLL模块的功能。

     
     
  • 相关阅读:
    定律法则
    thymeleaf模板引擎基础使用(转)
    OGNL是什么
    ZooKeeper可视化Web管理工具收集(待实践)
    Java下用Jackson进行JSON序列化和反序列化(转)
    JQuery获取select选中值和清除选中状态(转)
    Javascript控制回车键进行表单(form)提交(转)
    Javascript中数据与字符串互转(转)
    MySQL的limit用法及优化(转)
    Javascript中JSON的序列化和反序列化(转)
  • 原文地址:https://www.cnblogs.com/woshitianma/p/2832108.html
Copyright © 2011-2022 走看看