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/1ns

module  complex_fsm(
    input   wire    sys_clk         ,   //系统时钟50MHz
    input   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;
                          else
                              state <= IDLE;
    
                HALF    : if(pi_money == 2'b01)
                              state <= ONE;
                          else    if(pi_money == 2'b10)
                              state <= ONE_HALF;
                          else
                              state <= HALF;
    
                ONE     : if(pi_money == 2'b01)
                              state <= ONE_HALF;
                          else    if(pi_money == 2'b10)
                              state <= TWO;
                          else
                              state <= ONE;
    
                ONE_HALF: if(pi_money == 2'b01)
                              state <= TWO;
                          else    if(pi_money == 2'b10)
                              state <= IDLE;
                          else
                              state <= ONE_HALF;
    
                TWO     : if((pi_money == 2'b01) || (pi_money == 2'b10))
                              state <= IDLE;
                          else
                              state <= 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;
    else
        po_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;
    else
        po_money <= 1'b0;

endmodule

2.2. 仿真测试文件

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

`timescale  1ns/1ns

module  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 begin
    sys_clk    = 1'b1;
    sys_rst_n <= 1'b0;
    #20
    sys_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;
    else
        random_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;
    else
        pi_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;
    else
        pi_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_state

configure 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. 实验效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/554127.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达深度学习笔记:深度学习的 实践层面 (Practical aspects of Deep Learning)1.4-1.5

目录 第一门课&#xff1a;第二门课 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第一周&#xff1a;深度学习的 实践层面 (Practical aspects of Deep Learning)…

[C++][算法基础]分解质因数(试除法)

给定 n 个正整数 ai&#xff0c;将每个数分解质因数&#xff0c;并按照质因数从小到大的顺序输出每个质因数的底数和指数。 输入格式 第一行包含整数 n。 接下来 n 行&#xff0c;每行包含一个正整数 ai。 输出格式 对于每个正整数 ai&#xff0c;按照从小到大的顺序输出其…

同城O2O跑腿系统源码:外卖配送APP的技术架构与设计思路解析

今天&#xff0c;我将为大家详解同城O2O跑腿系统源码&#xff0c;剖析外卖配送APP的技术架构与设计思路。 一、用户端与商家端 用户端提供用户注册、登录、浏览菜单、下单、支付等功能&#xff0c;而商家端则负责商家入驻、菜单管理、订单处理等。这两个端的技术架构相对独立…

在Linux操作系统中文件目录特殊权限

管理员用户和普通用户都可以使用passwd命令来给用户设置密码 用户密码保存在/etc/shadow suid 4 sgid 2 sticky bit 1 suid&#xff08;只要是针对可执行文件进行设置。&#xff09; {当没有操作要求时&#xff0c;不可以擅自对shell&#xff0c;python脚本加上suid权…

java动态代理--cglib代理

1.概述 CGLIB动态代理是针对类实现代理&#xff08;无需实现接口&#xff09;&#xff0c;为了弥补jdk的不足&#xff0c; Cglib 不基于接口&#xff0c;是基于父子的继承关系&#xff08;被代理的对象是代理对象的父类&#xff09;&#xff0c;通过重写的形式扩展方法 2.定…

带头循环双向链表专题

1. 双向链表的结构 带头链表⾥的头节点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位节点不存储任何有效元素&#xff0c;只是站在这⾥“放哨 的” “哨兵位”存在的意义&#xff1a; 遍历循环链表避免死循环。 2. 双向链表的实现 2.1双向链表结构 typedef int DataTyp…

【光伏科普】光伏软件都有些什么功能?

光伏软件是为满足光伏行业特定需求而设计的工具&#xff0c;它涵盖了多个方面的功能&#xff0c;以支持光伏系统的设计、分析、优化和运营。以下是光伏软件通常具备的一些核心功能&#xff1a; 1.光伏系统设计 组件布局优化&#xff1a;根据地理位置、光照条件、阴影遮挡等因素…

开源在线表单工具 HeyForm 使用教程

HeyForm 是一个非常出色的开源在线表单工具&#xff0c;可以通过直观的拖拽式编辑器&#xff0c;快速构建出美观实用的表单。 HeyForm 的功能非常丰富&#xff1a; 支持丰富的输入类型&#xff0c;从基础的文本、数字到高级的图片选择、日期选择、文件上传等&#xff0c;一应俱…

Java web第三次作业

springboot入门程序撰写并启动 2.使用postman练习参数的获取。 简单参数 复杂参数 数组参数 日期参数 json参数 路径参数 3、体会前端页面向后端发送数据的过程。并且自己尝试将之前的注册页面的信息发送到服务端。 &#xff08;1&#xff09;、product.html的操作代码&#…

后端返回的数据中含有Null的则不在前端展示

方式 1&#xff1a;application 上加配置 只需要在配置文件 上&#xff0c;增加 如下配置。 application 格式配置&#xff1a; spring.jackson.default-property-inclusionnon_null yml 格式配置&#xff1a; spring:jackson:default-property-inclusion: non_null注意&a…

数字逻辑课程实验环境配置与使用说明

文章目录 I.虚拟机搭建1.1 Vmware安装1.2 Win XP安装1.3 xftp7安装 I. Quartus II安装II. 使用说明2.1 新建工程2.2 在工程中加入代码2.3 代码编译波形仿真 I.虚拟机搭建 1.1 Vmware安装 Vmware17安装教程 1.2 Win XP安装 Win XP安装教程 1.3 xftp7安装 给虚拟机添加FTP …

【团体程序设计天梯赛 往年关键真题 详细分析完整AC代码】L2-009 抢红包(排序) L2-010 排座位 (dfs)

【团体程序设计天梯赛 往年关键真题 详细分析&完整AC代码】搞懂了赛场上拿下就稳 【团体程序设计天梯赛 往年关键真题 25分题合集 详细分析&完整AC代码】&#xff08;L2-001 - L2-024&#xff09;搞懂了赛场上拿下就稳了 【团体程序设计天梯赛 往年关键真题 25分题合…

MCU最小系统的电源模块设计和复位模块的设计

最小操作系统就是一个电路&#xff0c;这个电路里面必须要的东西&#xff08;如人需要喝水吃饭温度等情况&#xff0c;才能或者&#xff09; 现在我们要解决这三个问题 这里V开头的&#xff0c;都是电源管脚 这里解释一下&#xff1a; 这里要注意哪些是电路电压&#xff0c;哪…

盲人导航功能特点:革新出行体验的实时避障应用深度解析

作为一名资深记者&#xff0c;我有幸亲历并详尽报道一款专为盲人群体设计的导航应用叫做蝙蝠避障&#xff0c;它不仅提供了精准的路线指引&#xff0c;更创新性地融入了实时避障功能。这款应用凭借其盲人导航功能特点&#xff0c;正以前所未有的方式提升盲人的出行自由度与安全…

YOLOv9最新改进系列:YOLOv9改进加入新型高效的多尺度注意力(EMA)模块保留每个通道的信息并减少计算成本!助力v9检测性能遥遥领先!

YOLOv9最新改进系列&#xff1a;YOLOv9改进加入新型高效的多尺度注意力&#xff08;EMA&#xff09;模块保留每个通道的信息并减少计算成本&#xff01;助力v9检测性能遥遥领先&#xff01; YOLOv9原文链接戳这里&#xff0c;原文全文翻译请关注B站Ai学术叫叫首er 详细的改进…

SqlServer专题

目录 1&#xff0c;连接数据库 2&#xff0c;连接池 1.何为连接池&#xff1f; 2.连接池运行原理。 3.如何查看连接池&#xff1f; 4.连接池注意事项。 3&#xff0c;一般SQL语句。 4&#xff0c;控制语句 1.判断语句 2.循环语句 5&#xff0c;视图 1.使用…

Java高阶私房菜:快速学会异步编程CompletableFuture

为了使主程代码不受阻塞之苦&#xff0c;一般使用异步编程&#xff0c;而异步编程架构在JDK1.5便已有了雏形&#xff0c;主要通过Future和Callable实现&#xff0c;但其操作方法十分繁琐&#xff0c;想要异步获取结果,通常要以轮询的方式去获取结果&#xff0c;具体如下&#x…

电脑开不了机?不要慌,三招教你快速解决!

电脑开不了机是我们在日常使用中可能遇到的一个严重问题&#xff0c;它会影响我们的工作和生活。了解如何解决电脑开不了机的问题对于维护电脑正常运行至关重要。本文将介绍三种常见的解决电脑开不了机的方法&#xff0c;帮助您快速恢复电脑的正常使用。 方法1&#xff1a;检查…

Java实现生成中间带图标的二维码

Java实现生成中间带图标的二维码 生成Base64格式的二维码&#xff0c;返回html渲染 package your.package;import com.google.zxing.*; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcod…

flask 应用程序

flask 程序示例 创建 hello.py 文件&#xff1a; # 导入 Flask 模块。Flask 类的一个对象是 wsgi 应用程序。 from flask import Flask# 创建app对象, Flask构造函数将当前模块的名称(__name__)作为参数。 app Flask(__name__)# route() 函数是一个装饰器&#xff0c;它告诉应…