第3篇的题材是模块化工程的仿真方法。现在只要是功能比较完善、规模比较大的FPGA设计都会采用模块化设计的方法。本文介绍在模块化设计过程中编写testbench并仿真的方法,Vivado对此有很好的特性支持,使用Quartus+ModelSim也可以达到同样的效果。


仿真第1个子模块

在开始设计前,根据设计划分好各功能模块(为了叙述方便,这里以对“FPGA数字信号处理(十三)锁相环位同步技术的实现”中设计的系统仿真为例)。编写好第一个子模块(本例中为双相时钟生成模块),在Vivado中添加仿真sim文件,编写testbench:

`timescale 1ns / 1ps
//-----------------------------------------------------
//   双相时钟信号生成模块测试
//-----------------------------------------------------
module clk_gen_sim;reg clk, rst;
wire clk_d1, clk_d2;
clk_gen i1
(.clk(clk),      //32MHz系统时钟.rst(rst),      //高电平有效复位信号.clk_d1(clk_d1),  //时钟1.clk_d2(clk_d2)   //时钟2
);always #10 clk = ~clk;initial beginclk = 1'b1;rst = 1'b1;#50;rst = 1'b0;#1000; $stop;
endendmodule

综合正确后,点击“Run Simulation”->“Run Behavioral Simulation”进行行为仿真,仿真结果如下图:

仿真结果正确(即功能与预期相符),则表明该子模块设计正确,可以开始下一个子模块的设计和仿真。


加入第N个子模块

和上节一样,设计好一个子模块,则添加一个仿真激励testbench文件,在仿真中确认功能正确性。最终的仿真文件清单如下所示:

Vivado对多模块、多文件的仿真提供了很好的特性支持。上面有多个testbench文件,分别对不同的模块进行仿真。当仿真好第一个模块后,需要仿真第二个模块时,对第一个模块对应的testbench点右键->“Disable File”,并将第二个模块对应的testbench点右键->“Set as Top”(当状态为Enable的仿真文件只有一个时会自动设置为Top),如下图所示:

如果想要重新仿真先前的模块,在testbench文件上点右键->“Enable File”即可重新将其置为有效。通过这样的方法可以完成所有模块的仿真。


多模块联合仿真

我们知道,模块化设计的代码,各个模块之间的联系是非常紧密的。对于简单的设计还比较好,可以像上节一样每个模块单独测试,各自编写testbench也并不复杂。而更多的设计在仿真时我们期望能直接使用第一个模块产生的信号,作为第二个模块的测试激励,即多模块联合仿真。

比如在“FPGA综合系统设计(七)基于DDC的两路信号相位差检测https://blog.csdn.net/fpgadesigner/article/details/80785174 ”中,在仿真DDC模块(数字下变频)时显然更希望直接使用信号生成模块(signal_gen)中产生的信号作为激励,而不是另外在testbench中生成一个信号作为激励。否则不仅费时费力,也没有测试到模块之间连接的正确性。

方法有两个:第一个是先编写好设计的顶层模块,不断的将子模块实例化到顶层模块中,只对顶层模块做仿真;第二个是在testbench中把需要的子模块都实例化好。

1. 第一种方法

Vivado可以观察模块的内部信号,在运行顶层模块的仿真后,Scope窗口内显示了顶层模块内包含的所有子模块。如下图所示:

仿真波形窗口内默认只显示顶层模块的接口和在testbench文件中定义的变量。如果要观察子模块内部的信号,在子模块上右键->“Add to Wave Window”,即可将相关信号添加到波形窗口。

借助于Vivado的这个特性,可以在设计过程中不断在顶层模块中实例化子模块,达到多模块联合仿真的目的。这样做的优点是在编写testbench代码上更省力,缺点是只有一个顶层模块的testbench,无法对各个子模块进行单独测试。

2. 第二种方法

在仿真一个子模块时希望用到其它子模块的输出信号,将两者都在testbench中实例化即可。和下面testbench代码类似:

`timescale 1ns / 1ps
module clk_iq_sim;reg clk, rst;
wire clk_d1, clk_d2;
wire clk_i, clk_q;
clk_gen i1
(.clk(clk),      //32MHz系统时钟.rst(rst),      //高电平有效复位信号.clk_d1(clk_d1),  //时钟1.clk_d2(clk_d2)   //时钟2
);
/*使用clk_gen模块的输出信号作为该模块的输入激励*/
clk_iq i2
(.clk(clk),      //32MHz系统时钟.rst(rst),      //高电平有效复位信号.clk_d1(clk_d1),  //时钟1.clk_d2(clk_d2),  //时钟2.clk_i(clk_i),.clk_q(clk_q)
);always #10 clk = ~clk;initial beginclk = 1'b1;rst = 1'b1;#50;rst = 1'b0;#1000; $stop;
endendmodule

这样做的好处是仍然可以保持每一个子模块都有一个对应的仿真激励文件,更方便功能测试和文件管理。尤其在经常需要修改和运行仿真的设计中,单独测试一个模块的运行时间比运行总体的顶层模块仿真要节省不少时间。


使用Quartus+ModelSim

Vivado自带的仿真(Vivado Simulation)已经足够好用,而使用Quartus时,由于其自带的波形仿真工具并不方便,经常需要调用ModelSim来仿真。使用Quartus+ModelSim也可以达到上面的效果。

多仿真文件的管理在Quartus主界面的Assignments菜单->Settings窗口中,如下图所示:

点击EDA Tool Settings下的Simulation,在Test Benches窗口中可以添加和管理多个testbench文件。在Compile test bench的下拉菜单里选择指定的一个testbench,调用ModelSim仿真时会读取相应的文件。

ModelSim仿真过程中也可以观察到顶层模块内部子模块的信号。在sim-Default窗口下可以看到顶层模块和子模块之间的实例化信息,选中相应的子模块,在Objects窗口(如果没有则在ModelSim主界面的View菜单中选中打开)下会显示出该子模块的相关信号。

对需要显示的信号点右键->“Add to”->“Wave”->“Selected Signals”,即可添加到波形窗口。点击“Run-All”重新运行仿真,新添加信号的波形便会显示出来。

Testbench编写指南(3)模块化工程的仿真方法相关推荐

  1. Testbench编写指南(4)自动化验证方法

    自动化验证testbench结果可以减少人工检查的时间和可能犯的失误,尤其对于比较大的设计.目前普遍使用三种自动化testbench验证方法: 数据库比较:首先创建一个包含预期输出的数据库文件(称作g ...

  2. Testbench编写指南(2)文件的读写操作

    Testbench编写指南是博主新开的一个系列,主要介绍在编写testbench时使用到的技巧,让编写者的水平不再仅仅停留在时钟信号.复位信号等简单信号的设置上,更好的完成对设计的仿真工作. 第2篇的 ...

  3. VHDL语言仿真激励文件testbench编写指南

    目录 前言 一.时钟和复位的模拟 二.文件读写 三.文件读写 总结 </

  4. Testbench编写指南(1)基本组成与示例

    对于小型设计来说,最好的测试方式便是使用TestBench和HDL仿真器来验证其正确性.一般TestBench需要包含这些部分:实例化待测试设计.使用测试向量激励设计.将结果输出到终端或波形窗口便于可 ...

  5. 编写AXI4协议读写BRAM并仿真验证

    前篇博文我们试验了AXI4-Lite协议读写BRAM,这里我们试验一下完整的AXI4协议.流程跟AXI4-Lite是一样的.省略的部分请参考:编写AXI4-Lite协议读写BRAM并仿真验证 一. 建 ...

  6. testbench编写流程的简单举例

    本文首发于公众号[木叶芯],版权所有,禁止转载. 如需转载,请在评论区留言或私信申请,经同意后可转载,否则属于侵权行为. 作者昵称:城外南风起 原文链接:testbench编写流程的简单举例 ---- ...

  7. TestBench编写_激励产生

    TestBench编写_激励产生 TestBench编写_激励产生 基本背景 读取函数介绍 a.$fopen函数使用 b.$fread函数使用 c.$fclose函数使用 实际使用 TestBench ...

  8. 【testbench】第1篇:testbench编写规则

    本文依据网络资料及工作经验整理而成,如有错误请留言. 文章为个人辛苦整理,付费内容,禁止私自转载. 文章专栏:<黑猫的FPGA知识合集> 1 概述 实现仿真需要自己增加testbench文 ...

  9. 30条HTML代码编写指南 for入门者

    本文总结了30条html代码编写指南,只要在编写HTML代码的过程中牢记它们,灵活运用,你一定会写出一手漂亮的代码,早日迈入专业开发者的行列. 1. 一定要闭合HTML标签 在以往的页面源代码里,经常 ...

最新文章

  1. java代码的执行机制_关于java代码的执行机制
  2. Mocha BSM产品亮点——策略管理
  3. Linux:目录操作
  4. 使用 Chrome Dev tools 分析应用的内存泄漏问题
  5. lstm代码_只需5行代码!LSTM时间序列建模以及预测
  6. 算法题目——第K大的数
  7. 网络连接数4000多正常吗_怀孕36周时胎儿发育情况是怎样的?胎儿体重有4斤多正常吗?...
  8. CSS3 之 flex
  9. linux 硬盘报警声
  10. 只知道CS224N?斯坦福最新推出NLU公开课CS224U
  11. [转载]一个本科生在世界五大顶尖咨询公司实习心得
  12. EM算法——解释 转载
  13. 教你如何安装字体包 ——思源免费商用字体
  14. AMS1117降压电路
  15. DH 算法迪菲-赫尔曼算法QUIC协议和HTTP3.0
  16. 服务器启动首选项不是虚拟盘,没法开启CPU虚拟化,BIOS没有开启的选项
  17. 三月校赛1006 wuli通通和Fibonacci (a[n]=f[n]*(n^m)的前k项和)
  18. 虚拟机导致无法上网_虚拟机无法上网问题解决方法
  19. matlab 画图直接存储_Matlab用plot画图后怎么保存图像
  20. 将手机、平板变成电脑第二屏

热门文章

  1. PAT乙级 难点救赎
  2. 图片使用base64位存储的利弊
  3. 巴塞尔协议中的计算公式_在巴塞尔协议I中,资本充足率的计算仅对()加权资产。...
  4. XILINX Ultrascale+ FPGA学习(2)——I/O接口组件原语和原生原语
  5. 什么是镜像?阿里云服务器镜像是什么?镜像怎么选?
  6. 服务引用定义配置(服务的注册与发现)
  7. 企业ERP系统选C/S架构还是B/S架构?
  8. plc触摸屏一体机的特点用处及PLC一体机的应用领域简介-深圳市顶控科技有限公司
  9. python线程池原理_Python定时器线程池原理详解
  10. python — 定时器