ModelSim入门教程和两个典型例子

  • 1 ModelSim入门教程
  • 2 组合逻辑电路的功能验证
    • 2.1 两位二进制全加器
  • 3 时序逻辑电路的功能验证
    • 3.1 八位加法器
  • 4 .v格式源代码和.v格式TestBench代码的3种编写方法
    • 4.1 LiberoSoc编程+ModelSim仿真
    • 4.2 ModelSim编程+仿真
    • 4.3 第三方编程+ModelSim仿真

1 ModelSim入门教程


  1. 使用LiberoSoc+ModelSim进行FPGA设计的前仿真
  2. 使用ModelSim进行FPGA设计的功能仿真

ModelSim是Model Technology(Mentor
Graphics的子公司)的HDL硬件描述语言的仿真软件,该软件可以用来实现对设计的VHDL、Verilog HDL
或是两种语言混合的程序进行仿真,同时也支持IEEE常见的各种硬件描述语言标准。
无论是从使用界面和调试环境,还是从仿真速度和效果上看,ModelSim都可以算的上是业界比较优秀的HDL语言仿真软件。它是唯一的单内核支持VHDL和Verilog
HDL混合仿真的仿真器,是做FPGA/ASIC设计的RTL级和门级电路仿真的好选择,它采用直接优化的编译技术,Tcl/Tk技术和单一内核仿真技术,具有仿真速度快,编译的代码与仿真平台无关,便于IP核的保护和加快错误程序定位等优点。

ModelSim不仅可以用于数字电路系统设计的功能仿真,还能用于时序仿真。一般在ModelSim创建工程的步骤包括创建工程、编写或者添加源代码、编译、启动仿真器、debug与分析。

2 组合逻辑电路的功能验证

本部分和第三部分分别是ModelSim-TestBench完整设计方法及实例4.1和4.2部分功能验证和时序验证的实例,顺便通过两个实例练习ModelSim的基本使用。

2.1 两位二进制全加器

要求:设计一个两位二进制全加器,全加器的A和B两个是1位二进制加数的输入端,CI是低位来的进位输入端,CO是向高位进位的输出端,SO是全加器的本位和值。

全加器Verilog代码:adder.v

module adder( so, co,a, b, ci );
input a, b, ci;
output so, co;
wire a, b, c, co,so;
assign {co, so} = a + b + ci;endmodule

代码中co是进位,so是相加之后的本位值。 input、output、inout预设值都是wire型,因此第四行代码可以省略。

全加器TestBench代码:adder_tb.v

`timescale 1ns/1ns
module adder_tb;
wire so,co;
reg a,b,ci;adder U(.so(so),.co(co),.a(a),.b(b),.ci(ci));initial // initializes the register variable to a definite value of one begin #20 a=0;b=0;ci=0;#20 a=0;b=0;ci=1;#20 a=0;b=1;ci=0;#20 a=0;b=1;ci=1;#20 a=1;b=0;ci=0;#20 a=1;b=0;ci=1;#20 a=1;b=1;ci=0;#20 a=1;b=1;ci=1;#20 $stop;
end
endmodule

仿真结果及分析
二位加法器的组合逻辑仿真结果如下:

分析:从上图可以看出a+b+ci确实是等于co+so的,而且上述仿真结果可以看出a,b,c的八种输入均以真值表的形式输入,输出也是符合预期的。

程序解读
第一次看代码,务必尽量看懂每一行。这样后续再看其他代码就会发现只需要补充记忆,而且补充记忆的会越来越少。

    1. 首先看程序第二行的
`timescale1ns/1ns

这句代码,这个是时间尺度指令,它是用来定义模块的仿真时间单位和时间精度的,其使用格式为:`timescale 仿真时间单位/时间精度,一般新建文件的模板也会有提示。

//`timescale <time_units> / <precision>

用于说明仿真时间单位和时间精度的数字只能是1、10或100,不能为其它的数字,单位可以是s、ms、us、ns、ps和fs。单位换算关系为:1 s = 10e3 ms = 10e6 us = 10e9 ns = 10e12 ps。

仿真时间单位是指的模块仿真时间和延时的基准单位,也就是说只有定义了仿真时间单位,程序中的延时符号"#"才有意义,如程序中的一行 #20 a = 0; b = 0; c = 0; 前面的 #20 就是延时20个时间基准单位,按照程序中的1ns这个基准,就延时了20个ns。需要说明的是该行程序的下一行 #20 a =0; b = 0; c = 1; 前面的延时20个ns是相对于前一个的延时来说的,也就是第二行在第一行完了之后延时20ns执行。这时候再看看仿真的波形图就不难理解最开始的线为什么是红色而不是正常的绿色的原因了,因为我们在程序中begin的下一行就是 #20 a =0; b = 0; c = 0; 它前面的延时20个ns是相对于begin的延时,也就是说程序开始的时候是什么都不做的,输出为不确定的值,过了20个ns才将全0赋给了a、b和ci,这个时候才是最开始的绿线的部分。

因此,如果我们把begin……end模块的最后一行

#20 $stop;

中的“#20”去掉,就观察不到仿真结果的最后一个输入的结果,就是下图蓝色圈中的部分。

    1. 用元件例化语句
adder U(.so(so),.co(co),.a(a),.b(b),.ci(ci));

把全加器设计电路嵌入到Test Bench程序中。引用模块时端口可以通过以下两种方式连接。
(1)adder U(so, co, a, b, c);
这种方式U(so, co, a, b, c)严格按照adder模块中的端口顺序连接,好处是不用标明原模块的端口名,但是必须严格对应。
(2)adder U(.a(a),.b(b),.ci(ci),.so(so),.co(co));
这种方式不要求严格对应,直接用“.端口(连接信号)”的形式表示,好处是提高了程序的可移植性和可读性。

    1. 程序的后面有一句
 #20 $stop;

这个是一个系统任务,用来暂停仿真过程的,将控制权交还给用户,用户在取得控制权以后可以输入其它的控制命令或者查看仿真结果等,之后可以从暂停的地方恢复仿真过程。$stop有两种表达形式,带参数的和不带参数的:

$stop;
$stop(n); //n可以取0、1或2

  • 不带参数的$stop等同于$stop(0),在暂停时不输出任何信息;
  • $stop(1)在暂停时输出当前仿真时刻和暂停处在程序中的位置;
  • $stop(2)不仅有$stop(1)的作用,还能输出仿真时占用内存大小和CPU时间。

为了测试$stop指令,将TestBench代码增加了几个stop断点,每次运行到stop断点时,在Transcript中输入run,运行的过程如下图示。
通过设置断点和$stop(0)可以发现,两个是一模一样的,即$stop(0\1\2)指令是采用Breakpoint的方式暂停的,不同的是$stop指令能输出运行时间、占用内存等更多的消息。

而用于退出仿真过程的系统任务是$finish,我们在点击Run(开始运行)的时候,系统会询问我们是否要结束仿真,假如我们选"是",这个系统任务会把ModelSim软件在完成仿真后关闭,假如我们选"否",则可以继续留在仿真界面。

3 时序逻辑电路的功能验证

3.1 八位加法器

源程序

module adder8(clk,aclr,load,load_din,dout);
// Portdeclarations
input clk;
input aclr;
input load;
input [7:0] load_din;
output [7:0] dout;//InternalVariables
wire  clk,aclr,load;
wire [7:0] load_din;
wire [7:0] dout;
reg [7:0] counter = 0;//CodeStarts Here
always @(posedge clk or negedge aclr)if(!aclr)counter <= 0;else if(load == 1)counter <= load_din;elsecounter <= counter + 1;  assign dout = counter;
endmodule

TestBench代码

`timescale 1ns/1ns
module adder8_tb;
reg clk, aclr, load;
reg [7:0] load_din;
wire [7:0] dout;initialbeginclk = 0;aclr = 1;load = 0;load_din = 0;#120 aclr = 0;#40  aclr = 1;#20  load = 1;load_din = 100;#20  load = 0;#100 $stop(0);
endalways #10 clk = ~clk;
adder8 U(.clk(clk), .aclr(aclr), .load(load), .load_din(load_din), .dout(dout));endmodule

分析

  1. 和组合逻辑不同的是,我们要利用always #10 clk = ~clk; 这个语句来产生周期为20个时间基准单位(1ns)的时钟(方波),即就是20ns的时钟信号。注意:时钟只能用always块才能生成,但要在initial块中赋给时钟的初始值(如clk=0或clk=1),如果不设置时钟初始值,则在仿真的时钟输出端是一个未知x(不变,就是例1中的那段红线了)。

  2. 在initial块中生成复位信号和加载信号,注意:一定要给复位信号和加载信号赋给初始值,否则和不设置时钟初始值一样会出现问题的。

  3. 在initial块的begin语句一开始就设置相关的初始值是一个好习惯。

  4. 和test_counter8.v进行全部的对比后发现和该仿真波形完全一致,仿真结束。load_din和load_out后面是采用16进制。

至于为什么是16进制,我现在也没搞懂????? 搞懂了,双击wave下面的信号,可以弹出radix进制选择。

4 .v格式源代码和.v格式TestBench代码的3种编写方法

最初不太清楚LiberoSoc与ModelSim之间的关系,也不熟悉ModelSim,只能在LiberoSoc中建立源代码和TestBench,然后通过Simulate打开ModelSim,观察仿真。摸得多了,现在总结了3种编写方法

4.1 LiberoSoc编程+ModelSim仿真

这也是Microsemi LiberoSoc软件自带的方式,是初学者最早接触的方法,方法是在LiberoSoc中建立project,然后添加HDL源代码和HDL TestBench,然后在ModelSim中进行仿真。

操作视频:使用LiberoSoc+ModelSim进行FPGA设计的前仿真

4.2 ModelSim编程+仿真

直接在ModelSim新建工程,然后添加文件时,选择新建文件,然后完成源代码和TestBench的编程工作,再在TestBench上右键选择compile all,就可以进行仿真。

缺点是软件自带的编辑环境不是很好,而且没有LiberoSoc自带的代码语法检测功能。

操作视频:使用ModelSim进行FPGA设计的功能仿真

4.3 第三方编程+ModelSim仿真

使用第三方的编辑工具是推荐的方法。建议使用UltraEdit或Notepad++这些专业的代码编辑软件。UltraEdit偏重于功能的强大和丰富的用户可定制化特性,而Notepad++更加注重易用性。两者在普通功能上差异不是特别大,根据自己的喜好选择一款即可。

也可以直接使用text编程,保存的时候注意存成".v"或".vhd"格式即可,然后ModelSim添加文件时加进去,这种方法也可以,但适用于熟练掌握Verilog语法的工程师。

ModelSim入门教程和两个典型例子相关推荐

  1. 【Konva入门教程】1、简单例子

    视频教程:[Konva入门教程]1.Konva介绍 Konva 是什么? Konva 是一个HTML5 Canvas JavaScript 框架,它通过对 2d context 的扩展实现了在桌面端和 ...

  2. ionic入门教程第五课-举例子说明异步回调$q及$q在项目中的用法

    继上一节中我们使用到$q来辅助完成了按需加载文件. 这节课我先简要的介绍一下$q 先从功能上做简要介绍的话: 我想通过一个故事来简要的介绍$q,就那最近比较普遍的叫餐服务举例吧 今天我想吃牛肉炒饭,所 ...

  3. php class类 教程,PHP类(Class)入门教程第2/2页

    用正确的小汽车对象学习和熟悉类的概念 很多书讲到类总喜欢拿小汽车来做例子,但是有些例子实在是又臭又烂误人子弟,骗人钱财,毁人前程,弱智低级到瞎编一个什么 set_color()函数来教人.实在是白白糟 ...

  4. php class 直接,PHP类(Class)入门教程

    以我的观点来说说PHP中的Class,用于表达的语言都是非正式的语言,也不能确定是否正确. 建立一个类很简单. class my_class{} ?> 类到底干什么呢?很多人都说是什么黑匣子,我 ...

  5. 迷你MVVM框架 avalonjs 入门教程(司徒正美)

    迷你MVVM框架 avalonjs 入门教程 关于AvalonJs 开始的例子 扫描 视图模型 数据模型 绑定属性与动态模板 作用域绑定(ms-controller, ms-important) 模板 ...

  6. 上下位机通讯协议_嵌入式中自定义协议的一些典型例子

    关于自定义协议,对于会的人很简单,对于不会的人就摸不着头脑.下面分享一些关于自定义协议的笔记. 什么是协议? 协议这个概念我觉得挺杂的.就像嵌入式的概念一样,说法不一,比如大家常常争论FPGA是不是嵌 ...

  7. Arduino极速入门教程——两篇文章让你会用Arduino(上)

    开坑使我快乐,本教程仅供初学者入门学习使用,要想深入还是得靠自己.本教程假设读者为完全无编程基础的普通人,所以行文可能会稍显啰嗦,但相信仍然会是目前比较精炼简短的教程. Arduino是啥 一个开源的 ...

  8. cad把图形切成两部分_CAD入门教程,最常用快捷键

    CAD是一款功能强大的绘图软件,如果把它学好了,找到的工作工资也是不会低的,但是从未接触过CAD的朋友想学习这个软件,一开始也是很困难的,但是想学就必须下苦工,因此小编为大家整理了CAD的入门教程,想 ...

  9. Arduino极速入门教程——两篇文章让你会用Arduino(下)

    接上篇关于Arduino基础环境配置.界面介绍和C语言基础,这一篇的内容为具体如何在Arduino中进行编程. 在VSCode上配置Arduino 什么是VSCode VSCode,即Visual S ...

  10. TensorFlow入门教程:1:安装和第一个例子程序

    TensorFlow™ 是Google开源的一个采用数据流图用于数值计算的开源库.截止到目前为止在github上已经获得超过6万个Star,已经成为深度学习和机器学习方面最为受欢迎的项目,炙手可热.这 ...

最新文章

  1. python系统提供构造函数传入参数_[ Python入门教程 ] Python函数定义和使用
  2. linux红帽网页中文乱码解决,【linux学习笔记】安装redhat时中文显示乱码(小方框)解决方法...
  3. SQL数据库学习之路(九)
  4. PHP_Memcache函数详解
  5. (55)_KPCR, _NT_TIB, _KPRCB
  6. python画圆填色_python turtle我想用五种颜色画五个圆,并且用画圆周的颜色填充,老是出问题,怎么回事,怎么修改?:python教程同心圆...
  7. 构思新巧的173dmba飞鸽
  8. 老牌社交网站Friends Reunited宣布关闭
  9. oracle 后台进程管理,Oracle background processes后台进程
  10. Test SRM Level Two: CountExpressions, Brute Force
  11. FreeCAD源码分析:Path模块
  12. OKR 与绩效考核结合的推进行业案例:医药行业
  13. two sample ttest paired ttst
  14. 《李尔王》:重拾李尔王的话语权力
  15. 数据建模:个人信用分是如何计算出来的?
  16. 获取股票历史数据(2)——数据保存/数据可视化
  17. eclipse下maven调试的技巧(Re-run Maven using the -X switch to enable full debug logging.)
  18. 计算机类专科学校排名,2017计算机专科学校排名一览表
  19. C++——return0
  20. C++:onnxruntime调用FasterRCNN模型

热门文章

  1. OpenCasCade鼠标移动高亮颜色设置与选中颜色设置
  2. OpenCascade一些常用的API
  3. C++里大写TRUE和小写true(BOOL与bool)
  4. matlab高等数学实验答案,高等数学实验matlab参考完整答案.doc
  5. 学习自己动手设计数据库
  6. 颜宁谈为何选择深圳:一拍即合!我麻溜地向普林斯顿递了辞职申请
  7. Windows如何重装系统
  8. 读书笔记:windows程序设计
  9. chrome中如何下载文本文件(不是直接打开)
  10. 学会这些知识普通人也能财务自由