当前位置: 首页 > article >正文

【EDA软件】【联合Modelsim仿真使用方法】

背景

业界EDA工具仿真功能是必备的,例如Vivado自带仿真工具,且无需联合外部仿真工具,例如MoodelSim。 FUXI工具仿真功能需要联合Modelsim,才能实现仿真功能。

方法一:FUXI联合ModelSim

1 添加testbench文件

新建top_tb.v文件,可以新建一个sim文件夹,把tb文件保存在里面。

Porject Manager->Add Sources->Add or create simulation sources->Create File,创建top_tb.v,创建后界面如图1:

图1

2 编写仿真代码并保存

top.v只输出了led这个信号,所以仿真代码比较简单,如图1,top.v代码如下所示:

// ============================================================
//
// Company:
// Engineer:
//
// Create Date: 05/14/2025 10:43:05   
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
// ============================================================
module top #(parameter  ADDR_WIDTH   = 10     ,parameter  DATA_WIDTH   = 16
)(output  reg     led
);localparam  DEPTH = (1 << ADDR_WIDTH);
localparam  CNT_THD = 11'd10;wire                        inner_osc_clk               ; // 80MHZ
wire                        mcu_clk                     ;
wire                        fpga_clk                    ;
wire                        pll_locked                  ;
wire                        sys_rst_n                   ;
wire                        por_locked                  ;wire                        clk                         ;
wire                        rst_n                       ;wire                        we                          ;
wire    [ADDR_WIDTH-1:0]    addr                        ;
wire    [DATA_WIDTH-1:0]    d_data                      ;
wire    [DATA_WIDTH-1:0]    q_data                      ;reg     [DATA_WIDTH-1:0]    memory      [DEPTH-1:0]     ;
reg     [DATA_WIDTH-1:0]    wr_data                     ;
reg     [DATA_WIDTH-1:0]    rd_data                     ;
reg     [ADDR_WIDTH-1:0]    wr_addr                     ;
reg     [ADDR_WIDTH-1:0]    rd_addr                     ;
wire                        wr_en                       ;
wire                        rd_en                       ;reg     [10:0]              wr_cnt                      ;
reg     [10:0]              rd_cnt                      ;reg                         we_1ff                      ;
reg                         rd_en_1ff                   ;oscillator_v1 u_oscillator_v1(.clkout     (  inner_osc_clk    )
);pll_v1 u_pll_v1(.clkin0     (   inner_osc_clk   ), // i.locked     (   pll_locked      ), // o.clkout0    (   fpga_clk        ), // o.clkout1    (                   )  // o
);por_v1_1 u_por_v1_1(.O          (   por_locked      )
);assign  sys_rst_n = pll_locked & por_locked;assign  clk = fpga_clk;
assign  rst_n = sys_rst_n;/*First Write*/
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginwr_cnt <= 11'd0;endelse if (wr_cnt < CNT_THD) beginwr_cnt <= wr_cnt + 1'b1;endelse;
end/*Write Full, then Read*/
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginrd_cnt <= 11'd0;endelse if (rd_en & (rd_cnt < CNT_THD)) beginrd_cnt <= rd_cnt + 1'b1;endelse;
endassign we = wr_cnt < CNT_THD ? 1'b1 : 1'b0;assign  wr_en = (we & (wr_cnt < CNT_THD)) ? 1'b1 : 1'b0;
assign  rd_en = ((~we) & (rd_cnt < CNT_THD)) ? 1'b1 : 1'b0;/*Memory Write Address Option*/
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginwr_addr <= {ADDR_WIDTH{1'b0}};endelse if (wr_en) beginwr_addr <= wr_addr + 1'b1;endelse;
end/*Memory Read Address Option*/
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginrd_addr <= {ADDR_WIDTH{1'b0}};endelse if (rd_en) beginrd_addr <= rd_addr + 1'b1;endelse;
end/*Set Write Data Value*/
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginwr_data <= {DATA_WIDTH{1'b0}};endelse if (wr_en) beginwr_data <= wr_data + 1'b1;endelse;
end/*Memory Write Data Option*/
always @ (posedge clk or negedge rst_n) begin : MEM_WRITEinteger i;if (!rst_n) beginfor (i = 0; i < DEPTH; i = i + 1) beginmemory[i] <= {DATA_WIDTH{1'b0}};endendelse if (wr_en) beginmemory[wr_addr] <= wr_data;endelse;
end/*Memory Read Data Option*/
always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginrd_data <= {DATA_WIDTH{1'b0}};endelse if (rd_en) beginrd_data <= memory[rd_addr];endelse;
endalways @ (posedge clk or negedge rst_n) beginif(!rst_n) beginwe_1ff <= 1'b0;rd_en_1ff <= 1'b0;endelse beginwe_1ff <= we;rd_en_1ff <= rd_en;end
endalways @ (posedge clk or negedge rst_n) beginif(!rst_n) beginled <= 1'b1;endelse if (we) beginled <= 1'b0;endelse if ((~we_1ff) & rd_en_1ff) beginif (&(rd_data ^~ q_data)) beginled <= 1'b1;endelse beginled <= 1'b0;endend
endassign d_data = wr_data;
assign addr = we ? wr_addr : rd_addr;
assign ce = ((wr_cnt < CNT_THD) || (rd_cnt < CNT_THD)) ? 1'b1 : 1'b0;emb_v1 emb_v1_SP (.clk        (   clk             ),.rstn       (   rst_n           ),.ce         (   ce              ), // i.we         (   we              ), // i.a          (   addr            ), // i.d          (   d_data          ), // i.q          (   q_data          )  // o
);endmodule

以上代码比较简单,通过寄存器搭建Memory,实现单端口RAM,以此验证单端口RAM IP。

3 设置仿真内容

3.1 设置Modelsim路径

Options->Simulation->ModelSim Path,路径为Modelsim的安装路径,一般为XXXX\Modelsim_10.5\win64;

3.2 设置Test Bench的Module name

Options->Simulation->ModelSim Path->Top Module Name of Test Bench,填写Module name;

3.3 设置Design Top的Module name

Options->Simulation->ModelSim Path->Instance Name of Design Top Module,填写Module name;

3.4 设置Test Bench Files

Options->Simulation->ModelSim Path->Test Bench Files,添加编写的仿真文件。

3.5 设置Modelsim *.do File

Options->Simulation->ModelSim Path->Modelsim *.do File,添加*.do文件。

暂时不好使,不推荐使用。

设置结果如图2:

图2

4 开始仿真

Flow->Simulation->RTL Simulation,最后点击RTL Simulation,如图3,开始仿真。

图3

自动会联合Modelsim工具,并弹出Modelsim的工具界面。

5 缺点

5.1 弹出界面后,需要手动进行run -all或者点击按钮,且没有固定的仿真时间,需要手动停止;

5.2 弹出界面只有top_tb的信号,需要手动自行添加信号,再运行;

5.3 修改文件需要从新执行4,比较浪费时间。

6 优点

FUXI可以很快的检查出文件的语法错误。

方法二:脚本构建 推荐

与top_tb.v同级目录下,添加三种文件,如图4:

图4

1 files.f 

添加需要编译仿真的testbench、 DUT(RTL)文件

内容如下:

top_tb.v
//rtl 仿真
D:/02_Fuxi/2025-03-28-win64-rel-99/data/lib/p0_sim.v
../src/ip/pll_v1.v
../src/ip/por_v1_1.v
../src/ip/oscillator_v1.v
../src/ip/emb_v1.v
../src/top.v

以上涉及1个问题,需要知道仿真模型;这个后续罗列出来。

2 start.do

汇总编译、波形设置的命令

#1 Create and Map the work lib
vlib work
vmap work work#2  Now compile all the files
vlog -64 -sv +acc -incr +define+SIM -timescale 1ns/1ns -work work -f files.f -l rtl.log#3  Start the simulator, log all waveforms, load wave file and run
vsim -voptargs="+acc" -sva +define+SIM -c work.top_tb -l sim.log -wlfdeleteonquit#4 Set the window types
view wave
view structure
view signals#5 Add signals or signals group to view wave
add wave -divider "System"
add wave -radix hexadecimal -group "System" top_tb/u_top/clk 
add wave -radix hexadecimal -group "System" top_tb/u_top/rst_nadd wave -divider "Memery Option"
add wave -radix hexadecimal -group "Memery" top_tb/u_top/mem_wr_en
add wave -radix hexadecimal -group "Memery" top_tb/u_top/mem_wr_addr
add wave -radix hexadecimal -group "Memery" top_tb/u_top/mem_wr_data
add wave -radix hexadecimal -group "Memery" top_tb/u_top/mem_rd_en
add wave -radix hexadecimal -group "Memery" top_tb/u_top/mem_rd_addr
add wave -radix hexadecimal -group "Memery" top_tb/u_top/mem_rd_dataadd wave -divider "EMB Option"
add wave -radix hexadecimal -group "EMB" top_tb/u_top/emb_wr_en
add wave -radix hexadecimal -group "EMB" top_tb/u_top/emb_wr_addr
add wave -radix hexadecimal -group "EMB" top_tb/u_top/emb_wr_data
add wave -radix hexadecimal -group "EMB" top_tb/u_top/emb_rd_en
add wave -radix hexadecimal -group "EMB" top_tb/u_top/emb_rd_addr
add wave -radix hexadecimal -group "EMB" top_tb/u_top/emb_rd_dataadd wave -radix hexadecimal top_tb/u_top/led #6 Set run Time
run 40ms

以上主要包含了6部分的设置。

3 批处理文件

如:run_sim.bat

echo pause  ::删除Modelsim生成的相关文件
RD work /s /q
DEL transcript vsim.wlf /qvsim -do start.do 
pause

通过批处理文件,调用start.do进行仿真。

4 优点

4.1 文件修改后,只需要在Modelsim CLI界面执行do start.do;

4.2 编辑start.do,添加需要观察的信号,进行波形观察。

5 缺点

修改文件需要编译才能知道文件的语法有错误,这稍微一点好时间可以接受。

因此可以联合FUXI,通过检查语法,当无语法错误后,进行编译仿真。

举例:

下图是结合方法1和方法2的优点,对单端口RAM的仿真结果。

例子连接:待上传。

相关文章:

【EDA软件】【联合Modelsim仿真使用方法】

背景 业界EDA工具仿真功能是必备的&#xff0c;例如Vivado自带仿真工具&#xff0c;且无需联合外部仿真工具&#xff0c;例如MoodelSim。 FUXI工具仿真功能需要联合Modelsim&#xff0c;才能实现仿真功能。 方法一&#xff1a;FUXI联合ModelSim 1 添加testbench文件 新建to…...

STM32 __main

STM32开发中__main与用户main()函数的本质区别及工作机制 在STM32开发中&#xff0c;__main和用户定义的main()函数是启动过程中的两个关键节点&#xff0c;分别承担运行时初始化和用户程序入口的职责。以下是它们的核心差异及协作机制&#xff1a; 一、定义与层级差异 ​__ma…...

【离散化 线段树】P3740 [HAOI2014] 贴海报|普及+

本文涉及知识点 C线段树 [HAOI2014] 贴海报 题目描述 Bytetown 城市要进行市长竞选&#xff0c;所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理&#xff0c;城市委员会为选民准备了一个张贴海报的 electoral 墙。 张贴规则如下&#xff1a; electoral…...

Python训练营打卡Day28

浙大疏锦行 DAY 28 类的定义和方法 知识点回顾&#xff1a; 1.类的定义 2.pass占位语句 3.类的初始化方法 4.类的普通方法 5.类的继承&#xff1a;属性的继承、方法的继承 作业 题目1&#xff1a;定义圆&#xff08;Circle&#xff09;类 要求&#xff1a; 1.包含属性&#x…...

MODBUS RTU通信协议详解与调试指南

一、MODBUS RTU简介 MODBUS RTU&#xff08;Remote Terminal Unit&#xff09;是一种基于串行通信&#xff08;RS-485/RS-232&#xff09;的工业标准协议&#xff0c;采用二进制数据格式&#xff0c;具有高效、可靠的特点&#xff0c;广泛应用于PLC、传感器、变频器等工业设备…...

CSP 2024 提高级第一轮(CSP-S 2024)单选题解析

单选题解析 第 1 题 在 Linux 系统中&#xff0c;如果你想显示当前工作目录的路径&#xff0c;应该使用哪个命令&#xff1f;&#xff08;A&#xff09; A. pwd B. cd C. ls D. echo 解析&#xff1a;Linux 系统中&#xff0c;pwd命令可以显示当前工作目录的路径。pwd&#x…...

六、绘制图片

文章目录 1.创建一个红色图片2.加载bmp图片3.加载png、jpg图片 前面的几个示例&#xff0c;我们已经展示过如果在Linux系统下使用xlib接口向窗口中绘制文本、线、矩形&#xff1b;并设置文本、线条的颜色。并利用xlib提供的接口结合事件处理机制完成了一个自绘按钮控件功能。有…...

Java 面向对象详解和JVM底层内存分析

先关注、点赞再看、人生灿烂&#xff01;&#xff01;&#xff01;&#xff08;谢谢&#xff09; 神速熟悉面向对象 表格结构和类结构 我们在现实生活中&#xff0c;思考问题、发现问题、处理问题&#xff0c;往往都会用“表格”作为工具。实际上&#xff0c;“表格思维”就是…...

深度学习---知识蒸馏(Knowledge Distillation, KD)

一、知识蒸馏的本质与起源 定义&#xff1a; 知识蒸馏是一种模型压缩与迁移技术&#xff0c;通过将复杂高性能的教师模型&#xff08;Teacher Model&#xff09;所学的“知识”迁移到轻量级的学生模型&#xff08;Student Model&#xff09;&#xff0c;使学生模型在参数量和计…...

基于CNN卷积神经网络的带频偏QPSK调制信号检测识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2024b 3.部分核心程序 &#xff08;完整版代码包含详细中文注释和操作步骤视频&#xff09…...

【DAY21】 常见的降维算法

内容来自浙大疏锦行python打卡训练营 浙大疏锦行 目录 PCA主成分分析 t-sne降维 线性判别分析 (Linear Discriminant Analysis, LDA) 作业&#xff1a; 什么时候用到降维 降维的主要应用场景 知识点回顾&#xff1a; PCA主成分分析t-sne降维LDA线性判别 通常情况下&#xff0c;…...

PostGIS实现栅格数据入库-raster2pgsql

raster2pgsql使用与最佳实践 一、工具概述 raster2pgsql是PostGIS提供的命令行工具,用于将GDAL支持的栅格格式(如GeoTIFF、JPEG、PNG等)导入PostgreSQL数据库,支持批量加载、分块切片、创建空间索引及金字塔概览,是栅格数据入库的核心工具。 二、核心功能与典型用法 1…...

校园社区小程序源码解析

基于ThinkPHP、FastAdmin和UniApp开发的校园社区小程序源码&#xff0c;旨在为校园内的学生和教职员工提供一个便捷的在线交流和服务平台。 该小程序前端采用UniApp进行开发&#xff0c;具有良好的跨平台兼容性&#xff0c;可以轻松发布到iOS和Android平台。同时&#xff0c;后…...

第6章:文件权限

一、文件权限概述 Linux为了保证系统中每个文件的安全&#xff0c;引入了文件权限机制。针对于系统中的每一个文件Linux都可以提供精确的权限控制。它可以做到不同的用户对同一个文件具有不同的操作权利。而通常这个权利包括以下3个&#xff1a; 读的权利&#xff08;Read&…...

使用 Python 连接 Oracle 23ai 数据库完整指南

方法一:使用 oracledb 官方驱动(推荐) Oracle 官方维护的 oracledb 驱动(原 cx_Oracle)是最新推荐方案,支持 Thin/Thick 两种模式。 1. 环境准备 pip install oracledb2. 完整示例代码 import oracledb import getpass from typing import Unionclass Oracle23aiConn…...

C语言| 指针变量的定义

C语言| 指针的优点-CSDN博客 * 表示“指向”&#xff0c;为了说明指针变量和它所指向的变量之间的联系。 int * i&#xff1b;//表示指针变量i里面存放的地址&#xff0c;所指向的存储单元里的【数据】。 【指针变量的定义】 C语言规定所有变量&#xff0c;在使用前必须先定…...

HTML 中的 input 标签详解

HTML 中的 input 标签详解 一、基础概念 1. 定义与作用 HTML 中的 <input> 标签是表单元素的核心组件&#xff0c;用于创建各种用户输入字段。作为一个空标签&#xff08;没有闭合标签&#xff09;&#xff0c;它通过 type 属性来决定呈现何种输入控件&#xff0c;是实…...

Python 在自动驾驶数据标签中的应用:如何让 AI 读懂道路?

Python 在自动驾驶数据标签中的应用:如何让 AI 读懂道路? 在自动驾驶系统中,数据就是生命线。不管是摄像头、激光雷达还是雷达传感器,这些设备每天都能产生 海量数据,但如果这些数据没有被正确标注,它们对 AI 来说毫无意义。那么,如何让自动驾驶系统准确理解道路环境呢…...

微信小程序之按钮短时间内被多次点击问题

做项目的时候碰到这个问题&#xff0c;按钮的功能做好了&#xff0c;但是总会出现按的太快&#xff0c;出现不可预料的问题。 解决方法之一&#xff1a;借助函数节流来实现 1、创建一个工具包&#xff08;throttle.js&#xff09;,通过封装一个高阶函数&#xff0c;对函数的执…...

动态规划(3)学习方法论:构建思维模型

引言 动态规划是算法领域中一个强大而优雅的解题方法,但对于许多学习者来说,它也是最难以掌握的算法范式之一。与贪心算法或分治法等直观的算法相比,动态规划往往需要更抽象的思维和更系统的学习方法。在前两篇文章中,我们介绍了动态规划的基础概念、原理以及问题建模与状…...

两个电机由同一个控制器控制,其中一个电机发生堵转时,另一个电机的电流会变大,是发生了倒灌现象吗?电流倒灌产生的机理是什么?

当两个电机由同一个控制器驱动&#xff0c;且其中一个电机发生堵转时&#xff0c;另一个电机的电流确实可能异常增大&#xff0c;但这不一定是典型的“倒灌现象”&#xff0c;而更可能是由于共母线电压波动或能量回馈导致的。以下是具体分析&#xff1a; 1. 现象是否属于“电流…...

Java 方法向 Redis 里操作字符串有什么需要注意的?​

在 Java 开发中&#xff0c;Redis 作为高性能的键值存储数据库&#xff0c;常被用于缓存数据、处理高并发场景等。当我们使用 Java 方法向 Redis 中操作字符串类型数据时&#xff0c;有许多关键要点需要格外注意。这些要点不仅关系到代码的正确性和性能&#xff0c;还影响着整个…...

ECMAScript 2018(ES2018):异步编程与正则表达式的深度进化

1.版本背景与发布 发布时间&#xff1a;2018年6月&#xff0c;由ECMA International正式发布&#xff0c;标准编号为ECMA-262 9th Edition。历史意义&#xff1a;作为ES6之后的第三次年度更新&#xff0c;ES2018聚焦于异步编程、正则表达式和对象操作的标准化&#xff0c;推动…...

IntelliJ IDEA给Controller、Service、Mapper不同文件设置不同的文件头注释模板、Velocity模板引擎

通过在 IntelliJ IDEA 中的 “Includes” 部分添加多个文件头模板&#xff0c;并在 “Files” 模板中利用这些包含来实现不同类型文件的注释。以下是为 Controller、Service、Mapper 文件设置不同文件头的完整示例&#xff1a; 1. 设置 Includes 文件头模板 File > Settin…...

从零开始认识 Node.js:异步非阻塞的魅力

Node.js 是一个基于 Chrome V8 引擎 的 JavaScript 运行时环境&#xff0c;用于在服务器端运行 JavaScript 代码。它的设计目标是让开发者能够用 JavaScript 构建高性能、可扩展的网络应用。以下是关于 Node.js 的详细介绍&#xff1a; 1. 核心特点 事件驱动与非阻塞 I/O&…...

【C语言练习】046. 编写插入排序算法

046. 编写插入排序算法 046. 编写插入排序算法C语言实现插入排序代码说明示例运行输入:输出:插入排序的特点一、插入排序的适用场景二、C语言代码示例及分步讲解代码实现代码解析三、示例执行过程四、性能分析五、总结046. 编写插入排序算法 插入排序(Insertion Sort)是一…...

【论文阅读】BEVFormer

〇、Introduction BEVFormer是现在端到端无人驾驶中常使用的一个Backbone&#xff0c;用于将六个视角下的图像转换为鸟瞰图视角下的特征&#xff0c;转换出的BEV特征则会被用于后续模块的特征交互。然而在这个模型设计的初期&#xff0c;其最本质的意图是为了提取用于各种CV任…...

IDEA编辑器设置的导出导入

背景 最近新换了电脑&#xff0c;因为之前是 Intel 芯片的 Mac&#xff0c;这次换了 arm 架构的 M 芯片的 Mac&#xff0c;旧 Mac 上的很多软件不兼容&#xff0c;所以就没有选择换机数据迁移&#xff0c;一点一点下载、配置了所有环境。 导出 IDEA 支持设置的导入导出&…...

手动实现 Transformer 模型

本文使用 Pytorch 库手动实现了传统 Transformer 模型中的多头自注意力机制、残差连接和层归一化、前馈层、编码器、解码器等子模块&#xff0c;进而实现了对 Transformer 模型的构建。 """ Title: 解析 Transformer Time: 2025/5/10 Author: Michael Jie &quo…...

成功案例丨从草图到鞍座:用先进的发泡成型仿真技术变革鞍座制造

案例简介 在鞍座制造中&#xff0c;聚氨酯泡沫成型工艺是关键环节&#xff0c;传统依赖实验测试的方法耗时且成本高昂。为解决这一问题&#xff0c;意大利自行车鞍座制造商 Selle Royal与Altair合作&#xff0c;采用Altair Inspire PolyFoam软件进行发泡成型仿真。 该工具帮助团…...