变量初始化的确定性

变量初始化的确定性

SystemVerilog初始化顺序
SystemVerilog标准增强了变量的内嵌初始化。SystemVerilog规定所有内嵌初始化先于仿真时刻0执行的事件。这就保证了如果Initial或者always过程块读取具有内嵌初始值的变量时取得正确的初始值,这个确定行为消除了Verilog标准中的不确定性。

注意:SystemVerilog变量内嵌初始化不引发仿真事件。

使用增强的SystemVerilog进行的仿真结果完全包含在允许的、但不确定的使用Verilog进行的仿真结果中,

logic resetN = 0; //声明并初始化reset
always@(posedge clock ,negedge resetN)if(!resetN) count <= 0; //reset低电平有效else count <= count + 1;

SystemVerilog中是仿真器在激活always过程块之前,先进行resetN的初始化。此后,仍然在0仿真时刻,当always块被激活后,它会等待下一个时钟上升沿或resetN下降沿。因为resetN的初始化已经发生了,计数器在0时刻不会被触发,而是等待下一个时钟上升沿或者resetN下降沿。

时序逻辑的异步输入初始化

--在仿真时刻0,使用两态数据类型施加复位
module counter (input wire clock,resetN,output logic[15:0] count
);
always@(posedge clock,negedge resetN)if(!resetN) count <= 0; //reset低电平有效else count <= count + 1;
endmodulemodule test;
wire [15:0] count;
bit clock;
bit resetN = 1;//resetN初始化无效值
counter dut(clock,resetN,count);
always #10 clock = ~clock;
initial beginresetN = 0;//在0时刻插入低电平有效的复位#2 resetN = 1; //在clock上升沿之前去除复位$display("\n count = %0d(expect 0)\n",count);#1 $finish;
end
endmodule

在上面的例子中,计数器有一个异步的复位输入。这个复位低电平有效,也就是在resetN跳变为0时,计数器会被复位。为了在仿真时刻0时对计数器进行复位,resetN输入必须跳变为逻辑0。如果resetN被声明为一个两态的数据类型,例如bit。如上面的测试平台例子,其缺省初始值是逻辑0。测试平台中的第一个测试是通过将resetN置为0来插入复位。第一个测试不会引发对resetN的仿真事件,因此counter模块的敏感列表不会因resetN的变化而触发过程块对counter复位。
为保证resetN置为0时resetN发生变化,resetN的带内嵌初始化声明为逻辑1–复位无效状态

bit resetN = 1;//resetN初始化无效值
提示:测试平台应该将变量初始化为无效 状态

SystemVerilog内嵌变量初始化的确定性可以保证0仿真时刻事件的发生顺序。如果变量使用内嵌初始化设成无效状态,然后使用initial或者always过程块置为有效状态,SystemVerilog就保证了内嵌初始化先发生,然后才进行过程块初始化赋值。

强制类型装换
SystemVerilog加入强制数据类型转换的能力。强制类型转换不同于在赋值时转变为数值。使用强制类型转换,不用赋值,在一个表达式内,一个数值就可以转换成一个新的类型。
(1)静态转换(编译时转换)

--数据类型强制转换
<type>'(<expression>) --将一个值强制转换成任意数据类型,包括用户自定义类型
7+int'(2.0 * 3.0)  //将(2.0*3.0)的结果转换为整型,然后加7--向量宽度强制转换
<size>'(<expression>)  --将一个值强制转换成任意向量宽度
logic[15:0] a,b,y;
y = a + b**16'(2); //将文本值2强制转换为16位宽--符号强制转换
<sign>'(<expression>)  --将一个值强制转换成有符号或无符号
shortint a,b;
int y;
y = y - signed'({a,b}); //将拼接结果强制转换为有符号值

静态强制转换和错误检测
静态强制转换操作符是一种编译时的转换。要强制转换的表达式在运行时总会被转换,而不会检查要转换的表达式是否在要转换成的类型的合法范围内。因此,必须注意不能将非法值赋给变量。

typedef enum{s1,s2,s3} states_t;
states_t state,next_state;
always_comb
beginif(state != s3)next_state = states_t'(state+1);elsenext_state = s1;
end

(2)动态强制类型转换
上面描述的SystemVerilog强制类型转换是一种编译时转换,转换操作总会运行,而不会检测结果的有效性。如果需要进一步的检验,SystemVerilog提供一个新的系统函数$cast,这是动态的,在运行时进行待转换数值的检查。
系统函数 $cast有两个变量,一个目标函数和一个源变量

$cast(dest_var,source_exp);int radius,area;
always@(posedge clock)$cast(area,3.154*radius**2);//强制转换操作符的结果被转换为area类型

$cast试图将源表达式赋给目标变量。如果赋值是无效的,将会报告一个运行时错误,并且目标变量保持不变。
将real类型转换成int类型,而实数太大,没有办法用int来描述
将一个数值转换成枚举类型,而它不在枚举类型的合法值列表中

typedef enum{s1,s2,s3} states_t;
states_t state,next_state;
always_latch 
begin$cast(next_state,state+1);
end

$cast也可作为任务被调用
$cast可以作为系统函数调用,它会返回一个状态标志来显示强制类型转换成功与否。如果转换成功, $cast返回1,;如果不成功, $cast函数返回0,并且不改变目标变量。作为函数调用时,不报告运行时错误。

typedef enum{s1,s2,s3} states_t;
states_t state,next_state;
int status;
always_latch 
beginstatus = $cast(next_state,state+1);if(status == 0)  //如果强制转换不成功next_state = s1;
end
注意:$cast函数不能和直接修改源表达式的操作符,如++或+=一块使用
$cast(next_state,++state);$cast的主要用途是将表达式的结果赋给枚举类型变量
使用编译时强制类型转换符用于综合

静态的编译时强制转换操作是可综合的。综合工具可能不支持动态的$cast系统函数。一般情况下,系统任务和系统函数不是一种可综合的结构。用于综合的更好的编码方式是使用静态强制转换操作符进行强制类型转换。

常数

parameter是一个可用确立(elaboration)时使用defparam或者内嵌参数重定义进行重新定义的常数。
specparam是一个可以在确立时从SDF文件中重定义的常数。
localparam是确立期常数,不能重定义。但是它的值可以基于其他常数。

常数负层次引用值不合法
常数不允许在自动任务和函数中
SystemVerilog加入了将任何变量声明为常数的能力–使用const关键字。const形式的常数知道确立完成后才被赋值。因为const常量在确立后才获得值,因此一个const常数可以:

  • 在自动任务和函数等动态环境中声明
  • 被赋予一个线网或变量值而非常数表达式
  • 被赋予一个对象值,这个值可以在任何设计层次定义。

const常数的声明必须包含数据类型

const logic[23:0] c1 = 7; //24为常数
const int c2 = 15; //32位常数
const real c3 = 3.14; // 实数常数
const c4 = 5; //错误,没有数据类型

const可以用在自动任务和函数中。
一个const常数实质是一个只能被初始化的变量。因为const形式的常数是在运行期间确定数值而不是确立期。一个const常数可以在自动任务和函数中声明,也可以在模块、静态任务和函数中声明。在begin…end块和fork…join块中声明的变量也可以声明为一个常数变量。

task automatic c;const int N = 5; //N是一个常数...
endtask

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

很好的Android论坛

需要的兄弟可以看一下 http://www.eoeandroid.com/?fromuid9379

用户自定义和枚举数据类型

用户自定义和枚举数据类型 用户自定义 1、typedef定义用户自定义类型 SystemVerilog同C一样&#xff0c;使用typedef关键字来建立用户自定义类型。用户自定义类型允许使用现有的数据类型建立新的数据类型。新的数据类型定义后&#xff0c;可以声明这个类型的变量 typedef int…

Keyboard驱动介绍

Keyboard驱动介绍 最近手里面没啥事&#xff0c;就想看看一些Driver的MDD层。 以前改过Keyboard Driver的PDD层&#xff0c;但是对它的MDD层还真是一片空白&#xff0c;这两天随便看了看Keyboard的MDD层&#xff0c;赶紧把东西记录下来&#xff0c;以防以过段时间忘记了。 很多…

GDI+不同的地方

研究了GDI处理图像的地方&#xff0c;发现它一些与众不同的地方&#xff0c;被它坑了一天。。。。。1、GDI的像素的原点默认你在左下角的&#xff0c;所以读取像素的顺序是从最低一行开始的(bottom-left)&#xff0c;其他一般的图像处理软件&#xff0c;像Photoshop&#xff0c…

关于结构体的内容

关于结构体的内容 结构体使用类似于C语言的语法来定义 结构体使用struct关键字声明。结构体内的成员可以是任何数据类型&#xff0c;包括用户自定义类型和其他的结构体类型。 struct{int a,b; //32位变量opcode_t opcode;//用户定义类型logic [23:0] adress;//24位变量bit er…

Pushing Policy Failed because Checkpoint Firewall “Load on module failed – no memory”

One day when pushing firewall policy from Checkpoint management server to UTM 272 cluster gateways, it failed and I got error message “Load on module failed – no memory” on one of cluster members. “Network Security Policy ‘Montreal_DMZ’ was prepared …

电池驱动介绍

电池驱动介绍 一&#xff0e;整体框架 电池驱动代码量很小&#xff0c;可是麻雀虽小&#xff0c;五脏俱全。与其他的很多Driver一样&#xff0c;分为PDDMDD层&#xff0c;双层之间通过PDD的如下导出接口相联系。 Programming element Description BatteryDrvrGetLevels…

将1bpp的bmp图像存储为1bpp或者2bpp的tiff格式

// 将1bpp的位图转换为 1bit/2bit tiff /** 参数&#xff1a;BYTE *src 二值图像的像素数据&#xff0c;不包含头部信息&#xff0c; 1bpp, int src_width 原图的宽度, in pixles,int src_height 原图的高度, in pixlesint bpp 转换tiff指定的bpp */ static BYTE *BW2Tif(…

关于联合体的内容

关于联合体的内容 联合体只储存一个值 联合体只存储一个元素&#xff0c;但这个元素可以有多种表示方法&#xff0c;每种表示可以是不同的数据类型。 联合体的声明语法类似于结构体&#xff0c;联合体的成员的引用也跟结构体一样。 union{int i;int unsigned u; }data; ... d…

Point-BERT:一种基于Transformer架构的点云深度网络

目录 1. 前言 2. Point Tokenization 3. Transformer Backbone 4. Masked Point Modeling 5. Experiments Reference 1. 前言 从PointNet [1] 开始&#xff0c;点云深度网络逐渐成为解决点云特征提取与语义分析的主要研究方向。尤其在OpenAI的GPT模型获得了突破性成果后&#…

GNS3 VoIP Lab (Cisco 3725 and CME 4.3)

Here is a simple VoIP Lab in GNS3 environment. It is only used for my lab test and recorded here for future reference. 1. Topology: GNS3 Topology:Logic Topology:xp(192.168.2.60)——–C3725 Router(192.168.2.10) 2. Enviroment: ESXi 5.5 (or Vmware Workstation…

谁知道这个代码片段干嘛的

int value 0xAAAA;for (int i0; i<8; i){int tmp value & 0x3; // 取出第两个比特位置if (tmp 0x0){//}else if (tmp 0x1){//}else if (tmp 0x2){//}else if(tmp 0x3){TRACE0("???");}TRACE1("tmp0x%x\n\n", tmp);value >> 2;}

关于数组的内容

关于数组的内容 Verilog数组声明的基本语法 <data_type><vector_size><array_name><array_dimension> 例如&#xff1a; reg[15:0] RAM [0:4095];//储存器数组SystemVerilog允许任何数据类型的非压缩数组 SystemVerilog将非压缩数组的声明进行了扩展…

Touch Driver介绍

Touch Driver介绍 一&#xff0e;相关知识介绍 1&#xff0e;Touch Driver的加载过程 GWES到[HKEY_LOCAL_MACHINE/HARDWARE/DEVICEMAP/TOUCH]的“Driver name”获取Driver DLL的名字&#xff0c;如果没有找到该键值&#xff0c;则使用默认名字Touch.dll。 Touch Driver的加…

BreadCrumb控件

BreadCrumb控件&#xff0c;如上图所示&#xff0c;即面包屑导航控件&#xff0c;类似于TreeCtrl&#xff0c;但不是一次显示所有的Item&#xff0c;VC 2010可以编译通过&#xff0c;稍微修改一下其他的也可以编译&#xff0c;源代码下载&#xff1a; http://download.csdn.net…

foreach数组循环结构体

foreach数组循环结构体 foreach循环遍历任何维数的数组 Systemverilog增加了foreach循环&#xff0c;它可用来对一维或多维数组中的元素进行迭代&#xff0c;而不必指定数组每个维度的宽度。foreach循环的自变量是数组名&#xff0c;它后面是方括号内用逗号隔开的循环变量列表…

Android简介

最近Android很火&#xff0c;小弟也想了解一下它的结构。跟CE或者Mobile比起来&#xff0c;它的结构是有点凌乱&#xff0c;也难怪&#xff0c;毕竟是基于别人的内核在上层开发了一些应用 ---------------------------------------------------------------------------------…

说不尽的刘恒

认识刘恒快三十年了&#xff0c;作为曾经的同事和他小说的责任编辑&#xff0c;我只写过他一篇文章&#xff0c;还是在二十多年前。有时候特别熟悉的人反而不知道从何写起&#xff0c;因为一想起往事&#xff0c;各种记忆像开闸的水一样涌满眼前&#xff0c;让人很难落笔。1985…

印前处理的“发动机”——RIP

对于许多印刷厂来说&#xff0c;数字印前技术仍是个谜&#xff0c;尤其是光栅处理器RIP。除了RIP之处&#xff0c;我们也总听说打印机的内置控制单元。其实&#xff0c;RIP与内置控制单元在本质上是一样的&#xff0c;但也有所不同。听说起来好像有些玄乎&#xff0c;下面我们来…

组合逻辑过程块

组合逻辑过程块 always_comb代表组合逻辑 always_comb过程块表示建立组合逻辑模型 always_comb if(!mode)y a b; elsey a - b;always_comb能推断出其敏感表 与通用always过程块不同&#xff0c;always_comb块的后面不需要指明敏感表。软件工具已经知道设计的意图是建立一个…