关于NC-Verilog常用的仿真选项

NC-Verilog命令选项详解
本文详细介绍了NC-Verilog环境下ncvlog、ncelab及ncsim工具的通用及特定选项,包括如何调用64位版本、指定文件路径、错误处理、仿真控制等方面的内容。

一、通用的基本选项

NC-Verilog中,有部分选项是ncvlog、ncelab和ncsim通用的选项,见表表 2‑1。

2‑1 ncvlog、ncelab和ncsim通用的基本选项

选项

说明

对应ncverilog选项

-64bit

调用64-bit版本的ncvlog

+nc64bit

-cdslib <pathname>

指定cds.lib文件的路径

+nccdslib+<arg>

-hdlvar <pathname>

指定hdl.var文件的路径

+nchdlvar+<arg>

-errormax <integer>

当错误数量达到指定数值时退出执行

+max_error_count+<arg>

-file <filename>

使用指定的命令行文件

-f <filename>

-logfile <filename>

定义输出的log文件名

-l <filename>

-ncerror <warning>

将指定“告警”信息的严重等级提高为“错误”

+ncerror+<arg>

-ncfatal <warning | error>

将指定“告警”或“错误”信息的严重等级提高为“致命”

+ncfatal+<arg>

-neverwarn

禁止打印所有告警信息

-w

-nocopyright

禁止打印版权信息

+ncnocopyright

-nolog

禁止产生log文件

+ncnolog

-nostdout

关闭屏幕打印,但不影响log文件的

+ncnostdout

-nowarn <warning>

关闭指定告警信息的打印

+ncnowarn+<arg>

-quiet

Log文件的安静模式,生成log文件时,屏蔽工具标识信息和调用工具时的命令行参数等。

-q

(-Q可以保存工具标识信息)

-status

打印内存和CPU的使用情况统计

+ncstatus

-update

增量仿真

+ncupdate

-version

打印工具的版本信息

+ncversion

-ieee1364

支持IEEE-1364的Verilog标准

+ieee1364

-ncinitialize

仿真0时刻,将设计中的变量初始化为指定值

+ncinitializ

二、ncvlog的常用选项

  2‑2 ncvlog的常用选项

选项

说明

对应ncverilog选项

-ams

支持AMS(Analog Mixed-Signal ,混合模拟信号)的编译

+ncams

-assert

支持PSL断言的编译检查

+assert

-checktasks

检查设计文件中是否存在非预定义的系统任务,例如$fsdbDumpvars

+ncchecktasks

-controlassert <file>

指定一个断言的控制文件,用来定义哪些断言打开,哪些断言关闭。

+controlassert+<arg>

-define <identifier[=value]>

定义一个变量

+define+<macro>

-design_top <design_name>

指定编译的设计最顶层module名

+ncdesign_top+<top>

-escapedname

输出信息中包括转义符,默认是不包括转义符

+ncescapedname

-incdir <directory>

在指定目录下搜索include文件

+incdir+<dirs>

-linedebug

支持行断点的设置和代码的单步执行

+nclinedebug

-noline

编译出错时,不定位代码行

+ncnoline

-sv

支持SystemVerilog,如果是单命令模式,缺省支持SV

+sv

-work <library>

定义指定的库为work库

+work+<lib>



三、ncelab的常用选项

2‑3ncelab的常用选项

选项

说明

对应ncverilog选项

-access [+] [-] <r|w|c>

设置仿真对象文件的访问权限,包括读r、写w和连接c,“+”表示增加,“-”表示删除。默认是没有任何权限。

+access<+/-rwc>

-covdut <dut_module>

指定某个DUTmodule进行覆盖率仿真

+nccovdut+<string>

-coverage <coverage_type>

仿真时使能某种类型的覆盖率,包括block、expr、fsm、toggle和all,即块、表达式、状态机、翻转率和全部

+nccoverage+<string>

-covfile <file_name>

指定一个参数文件名,用于配置覆盖率仿真的参数选项

+nccovfile+<file>

-defparam <parameter=value>

参数重定义

+defparam+<arg>

-maxdelays

应用specify块中min:typ:max延时的最大延时

+ncmaxdelays

-mindelays

应用specify块中min:typ:max延时的最小延时

+ncmindelays

-typdelays

应用specify块中min:typ:max延时的典型延时

+nctypdelays

-noassert

屏蔽快照snapshot中的PSL断言

+noassert

-noautosdf

关闭SDF自动反标

+noautosdf

-noneg_tchk

禁止Verilog代码或SDF反标中$setuphold和 $recrem时序检查中的负值。如果文件中出现负值,则负值当成0处理,并给出告警。

+noneg_tchk

-nonotifier

忽略时序检查时的notifier

+ncno_notifier

-nospecify

屏蔽Specify块中的时序以及SDF中的延时和时序检查

+nospecify

-notimingchecks

关闭时序检查

+notimingchecks

-no_tchk_msg

屏蔽时序检查时告警信息的显示

+no_tchk_msg

-ntcnotchks

如果设计中存在负延时的时序检查(NTC:negative timing check),那么仿真时使用-notimingchecks和不使用-notimingchecks选项有可能会出现不同的仿真结果。这种情况下,可以使用-ntcnotchks选项:产生负延时时序检查的延时,但不进行时序检查。

+ncntcnotchks

-timescale ‘unit/precision’

为设计中没有指定`timescale的module指定默认的timescale

+nctimescale+<arg>

-override_precision

用-timescale选项中的时间精度替换整个设计中的时间精度

+ncoverride_precision

-override_timescale

用-timescale选项中的参数替换整个设计中的时间单位和精度

+ncoverride_timescale

-partialdesign

在设计缺少某个模块层次时依然解析设计并产生仿真用的快照。

+partialdesign

-sdf_verbose

在SDF的log文件打印详细的SDF信息

+ncsdf_verbose

-snapshot <name>

指定快照(snapshot)文件的名称,默认是设计的最顶层模块名

+name+<name>


四、的常用选项

2‑4 ncsim的常用选项

选项

说明

对应ncverilog选项

-append_log

将多个ncsim命令的log文件存储到一个文件中

+ncappend_log

-batch

不等命令行的命令输入,直接开始仿真

+ncbatch

-covworkdir <dir>

指定覆盖率结果数据存储的work名,默认是cov_work/design/test

+nccovworkdir+<string>

-covdesign <design>

指定覆盖率结果数据存储的design名,默认是cov_work/design/test

+nccovdut+<string>

-covtest <test>

指定覆盖率结果数据存储的test名,默认是cov_work/design/test

+nccovtest+<string>

-profile

生成一个统计仿真过程中各个模块占用CPU时间的profile文件。

+ncprofile

-profoutput <file>

指定profile文件的文件名,默认是ncprof.out

+ncprofoutput+<file>

-dut_prof <file>

在仿真运行的profile文件中,增加一个报告指定DUT模块仿真时间的表格

+dut_prof+<file>

-gui

调用带SimVision的仿真器

+gui

-keyfile <filename>

指定一个key文件名,替换默认的ncsim.key

-k <filename>

-nokey

禁止生成key文件

+ncnokey

-licqueue

没有ncsim的license时,将仿真进入队列等候,直到获取license

+nclicq

-lps_off

关闭低功耗仿真(LPS:Low-Power Simulation)

+nclps_off

-ppe

仿真时调用“后处理环境”(PPE:Post Processing Environment)。PPE模式可以分析SHM模型中的仿真结果,在不使用license的情况下进行调试。

+ncppe

-input <script_file>

执行脚本文件中的TCL命令

+ncinput+<file>

-tcl

调用仿真器的交互模式,启动仿真器后停留在0时刻。

+tcl


五、ncverilog常用的基本选项

从上述4个表的对照可以发现,相对于三命令模式下的选项,大部分单命令模式的选项都由“-”变成了“+”,而且有些选项之前多了“nc”两个字母。

除了上述表格中对应的ncverilog选项之外,还有下面一些常用的ncverilog选项,见表表 2‑5。

 

2‑5 ncverilog其它一些常用的选项

选项

说明

+ncdebug

等同于+access+r

+nclibname+<name>

指定一个用于搜索的库

+ncrun

自动开始仿真

+nctfile+<file>

指定一个时序文件,用于进行时序检查的设置

+nclog_ncvlog+<logfile>

单独产生一个ncvlog的文件

+nclog_ncelab+<logfile>

单独产生一个ncelab的文件

+nclog_ncsim+<logfile>

单独产生一个ncsim的文件

+checkargs

检查命令行中选项的有效性

+compile

只进行ncvlog,不进行ncelab

-c

进行ncvlog和ncelab,不进行ncsim

+loadpli1=<arg>

指定PLI1库

+loadvpi=<arg>

指定VPI库

+noupdate

关闭默认的增量仿真模式

+v1995

关闭Verilog-2001标准,只支持Verilog-1995标准

-clean

删除以前的INCA_libs目录(如果存在的话)

-debug

等同于+access+rw

-F <filename>

搜索参数文件

-L<lib dir>

指定一个搜索库文件的目录

-v <file>

指定一个库文件

-y <directory>

指定一个库文件目录

+libext+<ext>

指定库文件的扩展名,与-y配合使用

+libverbose

打印库文件的详细信息

-ovm

支持OVM

-races

进行0延时的竞争冒险检查

-R

使用上次产生的快照文件进行仿真

-r <snapshot name>

使用指定的快照文件进行仿真

-s

调用快照文件,进入交互模式





<think>我们面对的问题是在使用NC-Verilog进行RTL无负荷仿真时,非阻塞赋值在输入与时钟同步变化的情况下,输出在同一个时钟沿就变化了,而不是预期的下一个时钟沿。这违背了非阻塞赋值的行为定义。 根据Verilog事件调度机制[^1],非阻塞赋值(NBA)应该按如下步骤执行: 1. 在活动事件区域计算右侧表达式(RHS) 2. 在非阻塞赋值更新区域更新左侧表达式(LHS) 理想情况下,当时钟上升沿到来时(活动事件区域): - 输入数据变化与时钟边沿同时发生(在同一个时间步) - 在活动事件区域,非阻塞赋值的RHS被计算(使用当前时间步的输入值) - 然后,在非阻塞赋值更新区域,LHS才会被更新(即输出变化) 然而,在同一个时间步内,如果输入数据的变化发生在时钟边沿之前(哪怕是0延迟),那么非阻塞赋值就会捕获到新的输入值,并在同一个时钟周期的非阻塞赋值更新区域更新输出。这就是为什么输出看起来在同一个时钟沿变化了。 但在用户描述的场景中,输入数据变化和时钟上升沿是同步的(同时发生),那么按照标准,输出应该是在下一个时钟沿才会变化。为什么会出现输出在本周期就变化呢? 可能的原因: 1. **输入数据变化与时钟边沿的时序关系**:虽然用户认为输入数据变化和时钟上升沿是同步的,但在仿真器中,事件调度可能存在细微的顺序差异。如果输入数据的变化事件被安排在时钟边沿事件之前(即使在同一时间步),那么非阻塞赋值就会捕获到新的输入值,从而导致输出在同一个时钟周期的非阻塞更新区域被更新。 2. **仿真工具的实现细节**:不同的仿真工具对同一时间步内事件的调度顺序可能不同。NC-Verilog可能在事件调度时,将输入数据变化事件安排在时钟边沿事件之前,导致非阻塞赋值在同一个周期内更新。 解决方法: 1. **确保输入数据变化在时钟边沿之后**:在测试平台中,将输入数据的变化安排在时钟上升沿之后的一个极小延迟(如`#1`)处。这样,时钟边沿事件发生时,输入数据还是原来的值(即变化发生在时钟边沿之后),非阻塞赋值捕获的是旧值,输出将在下一个时钟边沿更新新值。 例如,在测试平台中: ```verilog always @(posedge clk) begin // 在时钟上升沿之后改变输入数据 #1 data_in <= ...; end ``` 2. **使用非阻塞赋值驱动输入**:在测试平台中,使用非阻塞赋值来驱动设计的输入。这样,输入数据的变化会发生在非阻塞赋值更新区域,与设计的非阻塞赋值同步,从而避免竞争。 ```verilog // 测试平台 always @(posedge clk) begin // 使用非阻塞赋值改变输入数据 data_in <= ...; end ``` 3. **调整仿真选项**:NC-Verilog可能有相关的仿真选项来控制事件调度的顺序。可以查阅手册,尝试调整事件调度策略,使其符合预期。 4. **检查代码是否存在其他问题**:例如,输出信号是否受到其他组合逻辑的影响?或者时钟和数据的生成方式是否有问题? 示例代码分析: 假设我们有如下设计: ```verilog module d_flip_flop( input clk, input d, output reg q ); always @(posedge clk) begin q <= d; // 非阻塞赋值 end endmodule ``` 在测试平台中,如果这样驱动: ```verilog initial begin clk = 0; d = 0; forever #5 clk = ~clk; end // 在时钟上升沿同时改变数据 initial begin #10 d = 1; // 第一个上升沿后10ns,此时下一个上升沿在10ns(即时间20ns)处 // 但在时间10ns,我们同时触发了一个数据变化和下一个时钟上升沿在15ns?不对,需要调整时间点 // 改为在时钟上升沿时刻改变数据 #10; // 等到时间10ns,此时时钟下一个上升沿在10ns(因为时钟周期10ns,第一个上升沿在5ns,第二个在15ns?) // 实际上,我们想模拟在时钟上升沿(比如15ns)改变数据 #10 @(posedge clk) d <= 1; // 在15ns(上升沿)时,同时改变d end ``` 在这种情况下,在15ns时刻,时钟上升沿事件和数据变化事件同时发生。如果NC-Verilog先处理数据变化事件,那么非阻塞赋值就会捕获到新的d值(1),并在非阻塞更新区域更新q。这样,在15ns时刻,q就会变成1,而不是下一个周期。 解决:在测试平台中,使用非阻塞赋值,并且确保在时钟上升沿之后改变数据。修改测试平台: ```verilog initial begin @(posedge clk); // 等待一个上升沿 #1 d <= 1; // 在上升沿之后延迟1个单位再改变数据 end ``` 这样,在第一个上升沿时刻,d还是0,触发器捕获0;在下一个上升沿到来时,d已经稳定为1,触发器捕获1,输出在下一个上升沿改变。 总结:根本原因是输入数据变化与时钟上升沿在同一时间步内,且输入变化事件先于时钟边沿事件被处理。解决方法是将输入数据的变化安排在时钟上升沿之后(即使是一个很小的延迟)。 相关问题: 1. 在测试平台中,如何确保输入信号与时钟的时序关系满足建立和保持时间? 2. 不同仿真工具(如VCS、ModelSim)对同一时间步内事件调度的顺序是否一致? 3. 如何编写测试平台以避免Verilog仿真中的竞争冒险? </think>### 问题分析与解决方案 在NC-Verilog进行RTL无负荷仿真时,非阻塞赋值在时钟上升沿同步变化输入数据导致输出提前变化的问题,本质上是仿真事件调度中的**竞争冒险**问题。根据Verilog事件调度机制[^1]: 1. **非阻塞赋值(NBA)本质** 非阻塞赋值`<=`的执行分为两步: - 在活动事件区计算右侧表达式(RHS) - 在**非阻塞赋值更新区**更新左侧(LHS) ```verilog always @(posedge clk) begin output <= input; // RHS计算在时钟边沿,LHS更新在时间步结束 end ``` 2. **问题根源** 当输入数据变化与时钟上升沿**严格同时发生**时(同一仿真时间点): - 输入变化事件和时钟边沿事件被置于**同一调度队列** - NC-Verilog可能优先处理输入变化事件(视为组合逻辑更新) - 导致非阻塞赋值的RHS捕获到**新输入值** - 输出在**当前时钟周期**的非阻塞更新区被刷新 --- ### 解决方案 #### 方法1:延迟输入变化(推荐) 在测试平台中,强制输入数据变化**晚于时钟上升沿**,避开事件调度竞争: ```verilog initial begin // 时钟生成(假设周期10ns) forever #5 clk = ~clk; end initial begin // 输入数据在时钟上升沿后0.1ns变化 @(posedge clk); #0.1 data_in = new_value; end ``` - **原理**:`#0.1`确保输入变化事件被调度到时钟边沿事件之后 - **效果**:输出严格在**下一周期**时钟上升沿变化 #### 方法2:输入驱动使用非阻塞赋值 修改测试平台,用非阻塞赋值驱动输入信号: ```verilog reg [7:0] test_data; always @(posedge clk) begin test_data <= ... ; // 非阻塞驱动输入 end assign dut_input = test_data; ``` - **原理**:输入更新也被延迟到非阻塞更新区,与设计内部时序同步[^4] #### 方法3:调整仿真选项NC-Verilog中启用**严格时序检查**: ```bash ncverilog +nctimescale+1ns/1ps +strict_timing ``` - `+strict_timing`:强制按事件队列顺序处理 - `+nctimescale`:明确时间精度,避免零延迟歧义 #### 方法4:添加同步寄存器 在设计前端插入同步触发器: ```verilog reg [7:0] synced_input; always @(posedge clk) begin synced_input <= external_input; // 第一级同步 end always @(posedge clk) begin output <= synced_input; // 第二级非阻塞 end ``` - **效果**:输入变化至少延迟一个周期生效[^4] --- ### 问题验证方法 1. **Verdi波形调试** 添加中间信号观测调度顺序: ```verilog wire debug = $realtime; // 记录事件发生时间 ``` - 对比`clk上升沿`、`输入变化`、`输出更新`的时间戳 2. **断言监测** 插入SystemVerilog断言检测时序违规[^2]: ```verilog assert property (@(posedge clk) $stable(output)) else $error("Output changed in same cycle!"); ``` --- ### 根本原因总结 | 事件 | 预期发生区域 | 异常发生区域 | |---------------------|------------------|------------------| | 输入变化 | 时钟边沿前 | 与时钟边沿同时 | | 非阻塞RHS计算 | 活动事件区 | 活动事件区 | | **输出更新(LHS)** | **下一周期更新区** | **当前周期更新区** | 通过引入微小延迟(>仿真时间精度)可强制事件调度顺序符合预期[^1][^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值