【SystemVerilog验证】数据类型(待补充)

第二章

与Verilog相比,SystemVerilog提供了很多改进的数据结构

SystemVerilog引进了一些新的数据类型,它们具有如下优点:

  • 双状态数据类型:更好的性能、更低的内存消耗
  • 队列、动态和关联数组:减少内存消耗,自带搜索和分类功能
  • 类和结构:支持抽象数据类型
  • 联合和合并结构:允许对同一数据有多种视图(view)
  • 字符串:支持内建的字符序列
  • 美剧类型:方便代码编写,增加可读性

内建数据类型

Verilog-1995有两种基本的数据类型:变量和线网(net)

它们各自都可以有四种取值:0,1,Z,X

RTL代码使用变量来存放组合和时序值,变量可以是单比特或多比特的无符号数(reg7:0m),32比特的有符号数(integer),64比特的无符号数(time)或浮点数(real)

若干变量可以被一起存放到定宽数组里

所有的存储都是静态的,意味着所有的变量在整个仿真过程中都是存活的,子程序(routine)不能通过堆栈来保存形式参数和局部变量

线网可以用来连接设计当中的不同部分,例如门和模块示例。

尽管线网有很多用法,但是大多数设计者还是使用标量或矢量wire来连接各个设计模块的端口

逻辑(logic)类型

在Verilig中,初学者经常分不清reg和wire两者的区别?应该使用它们中哪一个来驱动端口?连接不同模块时又该如何做?

SystemVerilog对经典的reg 数据类型进行了改进,使得它除了作为一个变量以外,还可以被连续赋值、门单元、模块所驱动

为了与寄存器类型相区别,这种改进的数据类型被称为logic,任何使用线网的地方均可以使用logic,但要求logic不能有多个结构性的驱动,例如在对双向总线建模的时候。此时需要使用线网类型,例如wire

SystemVerilog会对多个数据来源进行解析以后确定最终值

复制代码
//logic类型的使用
module logic_data_type(input logic rst_h);
    parameter CYCLE=20;
    logic q,q_l,d,clk,rst_l;
    initial begin
        clk=0;    //过程赋值
        forever #(CYCLE/2) clk=~clk;
    end
    
    assign rst_l=~rst_h;    //连续赋值
    not n1(q_l,q);            //q_l被门驱动
    my_dff d1(q,d,clk,rst_l); //q被模块驱动
endmodule

由于logic类型只能有一个驱动,所以你可以使用它来查找网单中的漏洞

把你所有的信号都声明为logic而不是reg或wire,如果存在多个驱动,那么编译时就会出现错误。当然,有些信号你本来就希望它有多个驱动,例如双向总线,这些信号就需要被定义成线网类型,例如wire

双状态数据类型

相比四状态数据类型,SystemVerilog引入的双状态数据类型有利于提高仿真器的性能并减少内存的使用量

最简单的双状态数据类型是bit,它是无符号的。另四种带符号的双状态数据类型是byte,shortint,int和longint

  • bit

  • byte

  • shortint

  • int

  • longint

    //带符号的数据类型
    bit b; //双状态,单比特
    bit[31:0] b32; //双状态,32比特无符号数
    int unsigned ui; //双状态,32比特无符号数
    int i; //双状态,32比特无符号数
    byte b8; //双状态,8比特无符号数
    shortint s; //双状态,16比特无符号数
    longint l; //双状态,64比特无符号数
    integer i4; //四状态,32比特无符号数
    time t; //四状态,64比特无符号数
    real r; //双状态,双精度浮点数

可能会喜欢用 byte 替代 logic[7:0],因为写起来更短

但是byte有符号 类型,范围是 -128 ~ 127,而不是 0 ~ 255

复制代码
byte b = 255;   // 实际值是 -1,不是 255!

如果你需要一个 0~255 的无符号字节,可以写 byte unsigned

但仔细想想:byte unsigned 其实比 bit[7:0] 还要多打几个字,简洁性优势荡然无存

建议 :除非你明确需要有符号运算,否则表示无符号数据时优先使用**bit[7:0]logic[7:0]**

随机化中的隐患

有符号变量在随机化时可能产生意想不到的结果

例如,约束一个 byte 变量大于 0,你可能会得到 127 以下的合法值,但如果你没意识到它是有符号的,某些"正值"约束可能表现异常。

在把双状态变量连接到被测设计,尤其是被测设计的输出时务必要小心。如果被测设计试图产生X或Z,这些值就会被转换成双状态值,而测试代码可能永远页察觉不了。这些值被转换成0还是1并不必要,重要的是随时检查未知值的传播。使用($isunknown)操作符,可以在表达式的任意位出现X或Z时返回1

复制代码
//对四状态值的检查
if($isunknown(iport)==1)
    $display("@%0t:4-state value detected on iport %b",$time,iport);

使用格式符%0t和参数time可以打印出当前的仿真时间,打印的格式在timeformat()子程序中指定

双状态变量与四状态值的危险转换

SystemVerilog 引入了双状态 数据类型(bitbyteint 等),只有 0/1。

而硬件世界是四状态 的(logicregwire 等),可以有 0/1/X/Z。

当你把四状态值 (来自 DUT 输出)赋值给双状态变量时:

  • X 或 Z 会被自动转换成 0 或 1

  • 转换规则可能是 0,也可能是 1(取决于工具)

  • 测试代码完全察觉不到曾经存在 X 或 Z

这会导致一个严重问题:

设计中可能出现了 X 传播(未知值),但你的测试平台把它悄悄"抹平"了,误以为一切正常。

正确做法

连接 DUT 输出时,尽量使用四状态变量logic),而不是双状态变量。

如果必须使用双状态变量,或者你想主动检查是否存在 X/Z,可以使用系统函数 $isunknown()


$isunknown():检测未知值

if ($isunknown(iport) == 1)

$display("@%0t: 4-state value detected on iport %b",

$time, iport);

输出格式说明

  • %0t:打印时间值,不显示多余的空格

  • $time:返回当前仿真时间

  • $timeformat():可以预设时间打印格式

类型 有无符号 取值范围 状态数 注意
bit[7:0] 无符号 0 ~ 255 双状态 推荐用于无符号数据
byte 有符号 -128 ~ 127 双状态 随机化时易出错
byte unsigned 无符号 0 ~ 255 双状态 bit[7:0] 还啰嗦
logic[7:0] 无符号 0 ~ 255 四状态 连接 DUT 输出时首选

两条黄金法则

  1. 表示无符号数据时,优先用 bit[7:0] 而非 byte

  2. 连接 DUT 输出时,用 logic(四状态),不要用 bit(双状态) ,除非你主动用 $isunknown() 检测 X/Z

定宽数组

定宽数组的声明和初始化

常量数组

基本的数组操作------for和foreach

基本的数组操作------复制和比较

同时使用位下标和数组下标

合并数组

合并数组的例子

合并数组和非合并数组的选择

动态数组

队列

关联数组

链表

数组的方法

数组缩减方法

数组定位方法

数组的排序

使用数组定位方法建立记分板

选择存储类型

灵活性

存储器用量

速度

排序

选择最优的数据结构

使用typedef创建新的类型

创建用户自定义结构

使用struct创建新类型

对结构进行初始化

创建可容纳不同类型的联合

合并结构

在合并结构和非合并结构之间进行选择

类型转换

静态转换

动态转换

流操作符

枚举类型

定义枚举值

枚举类型的子程序

枚举类型的转换

常量

字符串

表达式的位宽

相关推荐
无忧.芙桃2 小时前
数据结构之单链表
c语言·开发语言·数据结构
HZ·湘怡2 小时前
二叉树 1
数据结构·算法·二叉树·
雨落在了我的手上2 小时前
Java数据结构(二):时间和空间复杂度
数据结构
悠仁さん2 小时前
list 链式表基本功能模拟实现(双向有头指针循环链表)
c语言·数据结构·链表·list
xxwxx__2 小时前
栈(Stack)详解:概念、实现与避坑指南
c语言·数据结构
少司府3 小时前
C++进阶:map和set的使用
开发语言·数据结构·c++·容器·stl·set·map
cpp_25013 小时前
P11375 [GESP202412 六级] 树上游走
数据结构·c++·算法·题解·洛谷·树形结构·gesp六级
川冰ICE3 小时前
JavaScript进阶③|Map_Set_WeakMap_WeakSet,新型数据结构
开发语言·javascript·数据结构
此生决int3 小时前
算法从入门到精通——字符串
数据结构·c++·算法·蓝桥杯