目录
数据类型
内建数据类型
相比于Verilog将寄存器(register)类型reg和线网(net)类型,例如wire区分地如此清楚。
在SV中新引入了一个数据类型logic,它们的区分和联系在于:
1、Verilog作为硬件描述语言,倾向于设计人员自身懂得所描述的电路中哪些变量应该被实现为寄存器,而哪些变量应该被实现为线网类型。这不但有利于后端综合工具,也更便于阅读和理解。
2、SV作为侧重于验证的语言,并不十分关切logic对应的逻辑应该被综合为寄存器还是线网,因为logic被使用的场景如果是验证环境,那么它只会作为单纯的变量进行赋值操作,而这些变量也只属于软件环境构建。
3、logic被推出的另外一个原因也是为了方便验证人员驱动和连接硬件模块、而省去考虑究竟该使用reg还是wire的精力。这既节省了时间,也避免了出错的可能。
与logic相对应的是bit类型,它们均可以构建矢量类型(vector),而它们的区别在于:
logic为四值逻辑,即可以表示O、1、X、Z
bit为二值逻辑,只可以表示O和1
问:SV为什么在已经有了四值逻辑的基础上还要再引入二值逻辑呢?
答:这是因为,SV在一开始设计的时候,就期望将硬件的世界与软件的世界分离开。在这里,硬件的世界指的就是硬件设计,所以四值逻辑属干那里,而软件的世界即验证环境,更多的是二值逻辑。
我们将四值逻辑的类型和二值逻辑的类型分别摘列出来:
四值逻辑类型:integer、logic、reg、net-type(例如wire、 tri)
二值逻辑类型:byte、shortint、int、longint、bit
如果按照有符号(最高位)和无符号的类型进行划分,那么可以将常见的变量类型划分为:
有符号类型:byte、shortint、int、longint、integer
无符号类型:bit、logic、reg、net-type(例如wire、tri)
1、在编码时一定要注意操作符左右两侧的符号类型是否一致,如果不一致,应该首先将其转换为同一类型再进行运算。对于转换方式,我们已经上面已经展示了一种转换方式——静态转换,即需要在转换的表达式前加上单引号即可,而该方式并不会对转换值做检查。
2、如果发生转换失败,我们也无从得知,所以与之对应的动态转换$cast(tgt,src)也被经常运用到转换操作中。
3、静态转换和动态转换均需要操作符号或者系统函数介入,我们统称为显式转换。
4、而不需要进行转换的一些操作,我们称之为隐式转换。
数组
数组声明:
int lo_hi[0:15]; // 16 ints [0]..[15]
int c_style[16]; // 16 ints [0]..[15]
//多维数组声明和使用:
int array2 [0:7][0:3]; // 完整声明
int array3 [8][4]; // 紧凑声明(左高右低)
array2[7][3] =1; // 设置最后一个元素
//初始化和赋值(大括号和单引号)
int ascend[4] ='{0,1,2,3}; // 对4个元素初始化
int descend[5];
descend ='{4,3,2,1,0}; //为5个元素赋值
descend[0:2] ='{5,6,7}; // 为前三个元素赋值
ascend ='{4{8}}; // 四个值全部为8
descend='{9,8,default:-1}; //{9,8,-1,-1,-1}
存储空间考量
下面的两个变量,都可以表示24bit的数据容量,那么从实际硬件容量的角度出发,哪种方式的存储方式更小呢?
bit [3] [7:0] b_pack; //合并,左高右低,3×8
bit [7:0] b_unpack[3]; //非合并,右高左低