Modelsim自动化仿真脚本(TCL)——简单实例

2024-04-18 16:28

本文主要是介绍Modelsim自动化仿真脚本(TCL)——简单实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1. Modelsim与TCL脚本的关系

2.实验文件

2.1设计文件

2.2仿真测试文件

2.3. 脚本文件

3. 实验步骤

3.1. 创建文件夹

3.2. 指定路径

3.3. 创建工程

3.4. 运行命令

3.4. 实验效果


1. Modelsim与TCL脚本的关系

       TCL(Tool Command Language)是一种脚本编程语言,由John Ousterhout在1988年开发。TCL是一种通用的、高级的、解释执行的脚本语言,它特别适合用于快速原型开发、测试、自动化任务以及GUI开发。TCL语言设计简单,易于学习和使用,它具有可扩展性,可以通过添加库来扩展其功能。
        ModelSim是由Mentor Graphics(现在是Siemens EDA的一部分)开发的一款行业标准的硬件描述语言(HDL)仿真工具。它支持多种HDL语言,包括VHDL、Verilog和SystemVerilog,用于验证数字电路和系统的设计。
       TCL脚本与ModelSim的关系在于,ModelSim提供了对TCL脚本的支持,使得用户可以使用TCL脚本来控制仿真环境、运行仿真、管理项目、处理结果等。通过编写TCL脚本,用户可以自动化ModelSim的许多操作,提高工作效率,实现复杂的测试流程,以及进行批量处理。例如,用户可以编写TCL脚本来自动化测试套件的执行,收集和分析仿真结果,甚至修改仿真参数并重新运行仿真,从而实现更加高效的验证流程。


2.实验文件

2.1. 设计文件

`timescale  1ns/1nsmodule  complex_fsm(input   wire    sys_clk         ,   //系统时钟50MHzinput   wire    sys_rst_n       ,   //全局复位input   wire    pi_money_one    ,   //投币1元input   wire    pi_money_half   ,   //投币0.5元output  reg     po_money        ,   //po_money为1时表示找零//po_money为0时表示不找零output  reg     po_cola             //po_cola为1时出可乐//po_cola为0时不出可乐
);//----------------------------------------------------------------------
//parameter define
//只有五种状态,使用独热码
parameter   IDLE     = 5'b00001;
parameter   HALF     = 5'b00010;
parameter   ONE      = 5'b00100;
parameter   ONE_HALF = 5'b01000;
parameter   TWO      = 5'b10000;//wire  define
wire    [1:0]   pi_money;
//reg   define
reg     [4:0]   state;//----------------------------------------------------------------------
//maincode
//pi_money:为了减少变量的个数,我们用位拼接把输入的两个1bit信号拼接成1个2bit信号。投币方式可以为:不投币(00)、投0.5元(01)、投1元(10),每次只投一个币
assign pi_money = {pi_money_one, pi_money_half};//第一段状态机,描述当前状态state如何根据输入跳转到下一状态
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)state <= IDLE;  //任何情况下只要按复位就回到初始状态else	case(state)IDLE    : if(pi_money == 2'b01)   //判断一种输入情况state <= HALF;else    if(pi_money == 2'b10)//判断另一种输入情况state <= ONE;elsestate <= IDLE;HALF    : if(pi_money == 2'b01)state <= ONE;else    if(pi_money == 2'b10)state <= ONE_HALF;elsestate <= HALF;ONE     : if(pi_money == 2'b01)state <= ONE_HALF;else    if(pi_money == 2'b10)state <= TWO;elsestate <= ONE;ONE_HALF: if(pi_money == 2'b01)state <= TWO;else    if(pi_money == 2'b10)state <= IDLE;elsestate <= ONE_HALF;TWO     : if((pi_money == 2'b01) || (pi_money == 2'b10))state <= IDLE;elsestate <= TWO;//如果状态机跳转到编码的状态之外也回到初始状态default :       state <= IDLE;endcase//第二段状态机,描述当前状态state和输入pi_money如何影响po_cola输出
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)po_cola <= 1'b0;else    if((state == TWO && pi_money == 2'b01) || (state == TWO && pi_money == 2'b10) || (state == ONE_HALF && pi_money == 2'b10))po_cola <= 1'b1;elsepo_cola <= 1'b0;//第二段状态机,描述当前状态state和输入pi_money如何影响po_money输出
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n ==	1'b0)po_money <= 1'b0;else if((state == TWO) && (pi_money == 2'b10))po_money <= 1'b1;elsepo_money <= 1'b0;endmodule

2.2. 仿真测试文件

关于随机数可参考:Modelsim怎样在测试平台文件中快捷使用随机数?-CSDN博客

`timescale  1ns/1nsmodule  tb_complex_fsm();//----------------------------------------------------------------------
//reg   define
reg         sys_clk;
reg         sys_rst_n;
reg         pi_money_one;
reg         pi_money_half;
reg         random_data_gen;//wire  define
wire        po_cola;
wire        po_money;
//----------------------------------------------------------------------
//初始化系统时钟、全局复位
initial beginsys_clk    = 1'b1;sys_rst_n <= 1'b0;#20sys_rst_n <= 1'b1;
end//sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50MHz
always  #10 sys_clk = ~sys_clk;//random_data_gen:产生非负随机数0、1
always@(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)random_data_gen <= 1'b0;elserandom_data_gen <= {$random} % 2;//pi_money_one:模拟投入1元的情况
always@(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)pi_money_one <= 1'b0;elsepi_money_one <= random_data_gen;//pi_money_half:模拟投入0.5元的情况
always@(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)pi_money_half <= 1'b0;elsepi_money_half <= ~random_data_gen;  //取反是因为一次只能投一个币,即pi_money_one和pi_money_half不能同时为1//------------------------------------------------------------
//将RTL模块中的内部信号引入到Testbench模块中进行观察打印
wire    [4:0]   state    = complex_fsm_inst.state;
wire    [1:0]   pi_money = complex_fsm_inst.pi_money;initial begin$timeformat(-9, 0, "ns", 6);$monitor("@time %t: pi_money_one=%b pi_money_half=%b pi_money=%b state=%b po_cola=%b po_money=%b", $time, pi_money_one, pi_money_half, pi_money, state, po_cola, po_money);
end
//------------------------------------------------------------
complex_fsm complex_fsm_inst(.sys_clk        (sys_clk        ),  //input     sys_clk.sys_rst_n      (sys_rst_n      ),  //input     sys_rst_n.pi_money_one   (pi_money_one   ),  //input     pi_money_one.pi_money_half  (pi_money_half  ),  //input     pi_money_half.po_cola        (po_cola        ),  //output    po_money.po_money       (po_money       )   //output    po_cola
);  endmodule

2.3. 脚本文件

1) `quit -sim` :退出仿真,如果当前modelsim中具有仿真运行,可以将其中止并退出仿真界面。

2)`.main clear ` :清除modelsim Transcript中的内容

3)`vlog "../src*.v" `:vlog为编译的意思,则../src/*.v代表路径。因为FPGA设计文件在src中,所以需要用../退到上一级文件夹,再选择src/*.v(即该文件夹下的所有.v文件)。如果不需要全部编译,也可以指定文件(vlog "../src/complex_fsm.v)。

4) `vsim`:这是ModelSim/QuestaSim的仿真命令,用于启动仿真。

5)`-t ns`这个选项指定了仿真的时间单位。在这个例子中,`-t ns`表示时间单位是纳秒(nanoseconds)。

6)`-voptargs=+acc`:这个选项用于传递参数给仿真优化工具(vopt)。`+acc`是一个特定的参数,它启用了额外的信号可访问性,这通常用于波形查看或交互式调试。`+acc`选项会使得更多的信号在仿真中可见,这可能会影响仿真的性能,因为需要跟踪更多的信号。

7)`work.tb_complex_fsm`: 这部分指定了要仿真的测试台(testbench)。`work`是ModelSim/QuestaSim中默认的库名,`tb_complex_fsm`是测试台的名字。在ModelSim/QuestaSim中,所有编译好的设计和测试台都存储在一个名为“work”的库中,除非你在编译时指定了其他的库名。

8)`add wave -driver {tb_complex_fsm}`:这条命令在波形显示中添加一个分隔线,用以区分不同的信号组。`{tb_complex_fsm}`是分隔线的标签。

9)`add wave tb_complex_fsm/*`: 这条命令将`tb_complex_fsm`测试台中所有的信号添加到波形显示中。``是一个通配符,表示添加所有信号。

10)`add wave -divider {complex_fsm}`: 这条命令在波形显示中添加一个分隔线,用以区分不同的信号组。`{complex_fsm}`是分隔线的标签。

11)`add wave -radix decimal tb_complex_fsm/complex_fsm_inst/*`: 这条命令将`tb_complex_fsm/complex_fsm_inst/`下的所有信号添加到波形显示中,并且设置这些信号的显示基数为十进制。这意味着这些信号的值将以十进制形式显示,而不是默认的二进制或十六进制。

12)`virtual function {(vir_new_signal)tb_complex_fsm/complex_fsm_inst/state} new_state`:这条命令创建了一个虚拟信号`new_state`,它是基于`tb_complex_fsm/complex_fsm_inst/state`信号的函数。这里的`vir_new_signal`可能是一个自定义的函数,用于处理`state`信号并生成`new_state`虚拟信号。

13)`add wave -color red -itemcolor blue tb_complex_fsm/complex_fsm_inst/new_state`: 这条命令将虚拟信号`new_state`添加到波形显示中,并设置该信号的波形颜色为红色,信号项的颜色为蓝色。

#---------------------------------------------------------------------
#基础配置
quit -sim
.main clear#---------------------------------------------------------------------
#包含文件
vlog "../src/*.v"
vlog "*.v"
#开始仿真
vsim -t ns -voptargs=+acc work.tb_complex_fsm#---------------------------------------------------------------------
# 添加虚拟类型
virtual    type {
{01 IDLE}
{02 HALF}
{04 ONE}
{08 ONE_HALF}
{16 TWO}
} vir_new_signal#----------------------------------------------------------------------
#添加波形
add wave -divider {tb_complex_fsm} add wave tb_complex_fsm/*
add wave -divider {complex_fsm_inst}
add wave -radix decimal tb_complex_fsm/complex_fsm_inst/* 
virtual    function {(vir_new_signal)tb_complex_fsm/complex_fsm_inst/state} new_state
add wave  -color red  -itemcolor blue  tb_complex_fsm/complex_fsm_inst/new_stateconfigure wave -timelineunits us
#----------------------------------------------------------------------
#运行
run 10us

3. 实验步骤

3.1. 创建文件夹

       按照如图方式创建modelsim_test、src、sim三个文件夹,并将FPGA设计文件和测试平台文件和自动化脚本放入如图文件夹

3.2. 指定路径

       打开软件更改Change Directory路径为3.1.的sim文件夹

3.3. 创建工程

3.4. 运行命令

3.4. 实验效果

这篇关于Modelsim自动化仿真脚本(TCL)——简单实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/915284

相关文章

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

springboot security验证码的登录实例

《springbootsecurity验证码的登录实例》:本文主要介绍springbootsecurity验证码的登录实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录前言代码示例引入依赖定义验证码生成器定义获取验证码及认证接口测试获取验证码登录总结前言在spring

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则