草庐IT

Verilog系统函数

一只特立独行的猪\n️ 2023-04-09 原文

Verilog系统函数

前言

在Verilog HDL语言中每个系统函数和任务前面都用一个标识符$来加以确认。这些系统函数和任务提供了非常强大的功能。
在ModelSim仿真时添加系统函数利于调试。

一、$width

(一)简介

$width函数用于检查信号脉冲的宽度是否达到要求。而信号脉冲的宽度由信号的reference_event和data_event决定,如下图所示

(二)$width 参数

ArgumentDescription翻译
reference_eventTimestamp edge triggered event时间戳边缘触发事件
(data_event - implicit)Timecheck edge triggered event时间检查边沿触发事件
limitNon-negative constant expression非负常量表达式
threshold(optional)Non-negative constant expression非负常量表达式
notifier (optional)Reg
  • 第二个参数data_event是一个隐式参数,也就是说你不用将它写出来。系统会根据你的第一个参数得到第二个参数,也就是说,第二个参数就是第一个参数的反向取沿。

  • 第3、4个参数是可选的。但是需要注意要使用第4个参数,首先要有第3个参数。

  • 第3个参数是门限值,如果脉冲小于该门限,是不会报violation的,没有该参数时该值为0。

(三)例子

1.下面的示例演示了一些合法和非法调用的示例:

//Legal calls
	$width ( negedge clr , lim ) ;
	$width ( negedge clr , lim , thresh , notif) ;
	$width ( negedge clr , lim , 0 , notif ) ;
//Illegal calls
	$width ( negedge clr , lim, , notif ) ;
	$width ( negedge clr , lim , notif);

2.如图

二、Specify参数

这些主要用于提供定时和延迟值,使用specparam关键字来声明。它既可以在specify块内使用,也可以在主模块体中使用。

// Use of specify block
specify
	specparam  t_rise = 200, t_fall = 150;
	specparam  clk_to_q = 70, d_to_q = 100;
endspecify

// Within main module
module  my_block ( ... );
 	specparam  dhold = 2.0;
 	specparam  ddly  = 1.5;

 	parameter  WIDTH = 32;
endmodule

三、$display

(一)简介

$display(p1,p2,....pn);
作用是用来输出信息,即将参数p2到pn按参数p1给定的格式输出。参数p1通常称为“格式控制”,参数p2至pn通常称为“输出表列”。$display自动地在输出后进行换行。

(二)格式说明

格式说明,由"%"和格式字符组成。它的作用是将输出的数据转换成指定的格式输出。格式说明总是由“%”字符开始的。对于不同类型的数据用不同的格式输出。下表中给出了常用的几种输出格式。

普通字符,即需要原样输出的字符。其中一些特殊的字符可以通过下表中的转换序列来输出。下面表中的字符形式用于格式字符串参数中,用来显示特殊的字符。

(三)例子

1.例1

module disp;
initial
    begin
        $display("\\\t%%\n\"\123");
    end
endmodule

输出结果

\%
"S

从上面的这个例子中可以看到一些特殊字符的输出形式(八进制数123就是字符S)。

2.例2

module disp;
reg[31:0] rval;
pulldown(pd);
initial
    begin
    rval=101;
    $display("rval=%h hex %d decimal", rval, rval);
    $display("rval=%o otal %b binary", rval, rval);
    $display("rval has %c ascii character value",rval);
    $display("pd strength value is %v",pd);
    $display("current scope is %m");
    $display("%s is ascii value for 101",101);
    $display("simulation time is %t",$time);
    end
endmodule

输出结果

rval=00000065 hex 101 decimal
rval=00000000145 octal 00000000000000000000000001100101 binary
rval has e ascii character value
pd strength value is StX
current scope is disp
e is ascii value for 101
simulation time is 0

更详细例子参考Verilog语法之十二:系统函数和任务

四、$monitor

(一)格式

$monitor(p1,p2,.....,pn);
$monitor;
$monitoron;
$monitoroff;

(二)功能

任务$ monitor提供了监控和输出参数列表中的表达式或变量值的功能。其参数列表中输出控制格式字符串和输出表列的规则和$display中的一样。

当启动一个带有一个或多个参数的$ monitor任务时,仿真器则建立一个处理机制,使得每当参数列表中变量或表达式的值发生变化时,整个参数列表中变量或表达式的值都将输出显示。

如果同一时刻,两个或多个参数的值发生变化,则在该时刻只输出显示一次。但在$ monitor中,参数可以是$ time系统函数。这样参数列表中变量或表达式的值同时发生变化的时刻可以通过标明同一时刻的多行输出来显示。如:$ monitor($time,,"rxd=%b txd=%b",rxd,txd);

在$display中也可以这样使用。注意在上面的语句中,“,"代表一个空参数。空参数在输出时显示为空格。

(三)$ monitoron/$ monitoroff

$ monitoron和$ monitoroff任务的作用是通过打开和关闭监控标志来控制监控任务monitor的启动和停止,这样使得程序员可以很容易的控制$monitor何时发生。

    1. 其中$ monitoroff任务用于关闭监控标志,停止监控任务$monitor
    1. $ monitoron则用于打开监控标志,启动监控任务$ monitor。
    1. 通常在通过调用$ monitoron启动$ monitor时,不管$ monitor参数列表中的值是否发生变化,总是立刻输出显示当前时刻参数列表中的值,这用于在监控的初始时刻设定初始比较值。
    1. 在缺省情况下,控制标志在仿真的起始时刻就已经打开了。在多模块调试的情况下,许多模块中都调用了$ monitor,因为任何时刻只能有一个$ monitor起作用,因此需配合$ monitoron与$ monitoroff使用,把需要监视的模块用$ monitoron打开,在监视完毕后及时用$ monitoroff关闭,以便把$monitor 让给其他模块使用。
    1. $ monitor与$ display的不同处还在于$ monitor往往在initial块中调用,只要不调用 monitoroff,$ monitor便不间断地对所设定的信号进行监视。

五、$ time/$ realtime

(一)$time

1.简介

.时间度量系统函数,在Verilog HDL中有两种类型的时间系统函数: t i m e 和 time和 timerealtime。用这两个时间系统函数可以得到当前的仿真时刻。

$time可以返回一个64比特的整数来表示的当前仿真时刻值。该时刻是以模块的仿真时间尺度为基准的。

2.例子

`timescale 10ns/1ns
module test;
    reg set;
    parameter p=1.6;
    initial
    begin
        $monitor($time,,"set=",set);
        #p set=0;
        #p set=1;
    end
endmodule

输出结果为:

0 set=x
2 set=0
3 set=1

在这个例子中,模块test想在时刻为16ns时设置寄存器set为0,在时刻为32ns时设置寄存器set为1。但是由$time记录的set变化时刻却和预想的不一样。这是由下面两个原因引起的:

  1. $ time显示时刻受时间尺度比例的影响。在上面的例子中,时间尺度是10ns,因为$ time输出的时刻总是时间尺度的倍数,这样将16ns和32ns输出为1.6和3.2。

  2. 因为$time总是输出整数,所以在将经过尺度比例变换的数字输出时,要先进行取整。在上面的例子中,1.6和3.2经取整后为2和3输出。注意:时间的精确度并不影响数字的取整。

(二)$realtime

1.简介

$ realtime和$ time的作用是一样的,只是$ realtime返回的时间数字是一个实型数,该数字也是以时间尺度为基准的。

2.例子

举例说明:

`timescale10ns/1ns
module test;
    reg set;
    parameter p=1.55;
    initial
    begin
        $monitor($realtime,,"set=",set);
        #p set=0;
        #p set=1;
    end
endmodule

输出结果为:

0 set=x
1.6 set=0
3.2 set=1

从上面的例子可以看出,$ realtime将仿真时刻经过尺度变换以后即输出,不需进行取整操作。所以$ realtime返回的时刻是实型数。

参考

Verilog的Timing check函数之$width

Verilog初级教程(19)Verilog中的参数

静态时序分析—脉冲宽度检查(Pulse Width Check)

Verilog语法之十二:系统函数和任务

verilog中的$ display和$ wirte

有关Verilog系统函数的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  4. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  5. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  6. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  7. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  8. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  9. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

  10. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

随机推荐