前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ModelSim 使用【一】介绍

ModelSim 使用【一】介绍

作者头像
数字积木
发布2021-04-15 10:53:45
1.6K0
发布2021-04-15 10:53:45
举报
文章被收录于专栏:数字积木

【注】本文为系列教程,使用同一个仿真代码,关注公众号“数字积木”,对话框回复“ modelsim_prj ”,即可获得。这是系列第一篇。

1,ModelSim软件介绍

Mentor 公司的 ModelSim 是工业界最优秀的语言仿真器,它支持 XP、Win7 和 Linux 系统,是单一内核支持 VHDL 和 Verilog 混合仿真的仿真器。它采用直接优化的编译技术、Tcl/Tk 技术、单一内核仿真,不仅编译仿真速度业界最快、编译的代码与平台无关,而且便于保护 IP 核。它还提供了最友好的调试环境,具有个性化的图形界面和用户接口,为用户加快调试提供强有力的手段,它是 FPGA/ASIC 设计的首选仿真软件。

Modelsim 有几种不同的版本:SE(System Edition)、DE(Deluxe Edition)、PE(Personal Edition)和 OEM(Orignal Equipment Manufactuce,即原始设备制造商),其中 SE 是最高级的版本,而集成在 Actel、Atmel、Altera、Xilinx 以及 Lattice 等 FPGA 厂商设计工具中的均是OEM 版本。我们这里选择使用的是 Altera 公司提供的 OEM 版本,也就是我们常说的 ModelSim AE(即:ModelSim-Altera Edition)。下面我们给出 Altera 官方对 ModelSim AE 的介绍,如图 所示。

该图中我们可以看出,Modelsim Altera 是有两个版本的,一个是免费版本(ModelSim-Altera Starter Edition);一个是收费版本(ModelSim-Altera Edition)。由于图中给出了收费版本和免费版本的区别,所以我们就不在进一步介绍它们了,这里我们说一下,ModelSim-Altera 版软件与 ModelSim PE/DE 软件的区别,ModelSim-Altera 版软件仅支持 Altera 门级库。ModelSim-Altera 版软件包括 ModelSim PE 的基本特性,包括了行为仿真、HDL 测试台和Tcl 脚本。但是,ModelSim-Altera 版软件并不支持 ModelSim PE 的可选特性,ModelSimAltera 版的仿真性能要低于 ModelSim PE/DE 软件。

2,ModelSim使用流程

介绍完了 ModelSim 软件,接下来我们再来介绍一下 ModelSim 使用流程。在介绍 ModelSim的使用流程之前,我们需要对给大家说明一下仿真的两个概念,仿真一般分为前仿真与后仿真:(1) 前仿真也就是纯粹的功能仿真,主旨在于验证电路的功能是否符合设计要求,其特点是不考虑电路门延迟与线延迟。(2) 后仿真也就是时序仿真。是指电路已经映射到特定的工艺环境下,综合考虑电路的路径延迟与门延迟的影响,验证电路在一定时序条件下是否满足设计构想的过程。说完了仿真的两个概念,接下来我们在来说一说 ModelSim 的使用,ModelSim 的使用主要分为两种情况,第一种就是通过 Quartus II 软件调用我们的 ModelSim 来进行仿真,这种情况也就是我们通常所说的自动仿真。第二种情况就是直接打开 ModelSim 进行仿真,不经过我们的Quaruts II 软件,这种情况也就是我们通常所说的手动仿真。不管是自动仿真还是手动仿真,它们的都遵循以下 5 个步骤:

(1) 新建工程。

(2) 编写 Verilog 仿真文件。

(3) 编写 Testbench 仿真文件。

(4) 开始功能仿真。

(5) 开始时序仿真。

当我们执行了仿真以后,ModelSim 软件会根据我们的设计文件和仿真文件生成波形图,最后,我们观察波形并判断设计的代码功能是否正常。前仿真完成以后,接下来我们就需要进行后仿真了,后仿真与前仿真的步骤大体相同,只不过中间需要添加仿真库、网表和延时文件等步骤。这里我们要注意的是,对于时序要求不严格的小规模设计,我们一般只进行功能仿真。

【注】本系列教程使用的源码和testbench代码如下:

源码:

代码语言:javascript
复制
module Verilog_First
(
  //输入端口
  CLK_50M,RST_N,  
  //输出端口
  LED1    
);  
//---------------------------------------------------------------------------
//--  外部端口声明
//---------------------------------------------------------------------------
input       CLK_50M;    //时钟的端口,开发板用的50M晶振
input      RST_N;      //复位的端口,低电平复位
output      LED1;      //对应开发板上的LED

//---------------------------------------------------------------------------
//--  内部端口声明
//---------------------------------------------------------------------------
reg  [26:0]  time_cnt;    //用来控制LED闪烁频率的定时计数器
reg      led_reg;    //用来控制LED亮灭的显示寄存器
//设置定时器的时间为1s,计算方法为  (1*10^6)us / (1/50)us  50MHz为开发板晶振
//parameter SET_TIME_1S = 27'd49_999_999;      
  parameter SET_TIME_1S = 27'd49  ;    //用于仿真
//---------------------------------------------------------------------------
//--  逻辑功能实现  
//---------------------------------------------------------------------------
//时序电路,实现1s的定时计数器
always @ (posedge CLK_50M or negedge RST_N)  
begin
  if(!RST_N)                //判断复位
    time_cnt  <=  27'h0;        //初始化time_cnt值
  else if(time_cnt == SET_TIME_1S)    //判断1s时间
    time_cnt = 27'h0;        //如果到达1s,定时计数器将会被清零
  else
    time_cnt = time_cnt + 27'h1;//如果未到1s,定时计数器将会继续累加
end

//---------------------------------------------------------------------------
//时序电路,判断时间,控制LED的亮或灭
always @ (posedge CLK_50M or negedge RST_N)  
begin
  if(!RST_N)                //判断复位
    led_reg <=  1'b0;          //初始化led_reg值
  else if(time_cnt == SET_TIME_1S)    //判断1s时间
    led_reg = ~led_reg;      //如果到达1s,显示寄存器将会改变LED的状态
  else
    led_reg = led_reg;        //如果未到1s,显示寄存器将会将保持LED的原状态
end

assign LED1 = led_reg;          //最后,将显示寄存器的值赋值给端口LED1

endmodule  

testbench:

代码语言:javascript
复制
`timescale 1 ps/ 1 ps
module Verilog_First_vlg_tst();

reg CLK_50M;
reg RST_N;
// wires                                               
wire LED1;

// assign statements (if any)                          
Verilog_First i1 (
// port map - connection between master ports and signals/registers   
  .CLK_50M(CLK_50M),
  .LED1(LED1),
  .RST_N(RST_N)
);

initial                                              
begin
  #0 CLK_50M = 1'b0;
  #10000 RST_N = 1'b0;
  #10000 RST_N = 1'b1;
  #10000000 $stop;
end

always #10000 
begin
  CLK_50M = ~CLK_50M;    
end                                                  
endmodule

欢迎关注,更精彩的内容等着你!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数字积木 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档