【SystemVerilog】数据类型(4)队列、枚举

news/2024/5/19 19:20:32 标签: systemverilog, 数字IC

        本篇文章对SV的其他数据类型进行介绍。包括:链表、队列、枚举、typedef重定义、用户自定义、常量、字符串。


目录

一、队列

二、枚举

三、字符串

四、其他


一、队列

        SV 引进了一种新的数据类型——队列它结合了链表和数组的优点。队列与链表相似,可以在一个队列中的任何地方增加或删除元素,这类操作在性能上的损失比动态数组小得多,因为动态数组需要分配新的数组并复制所有元素的值 ;队列与数组相似,可以通过索引实现对任一元素的访问,而不需要像链表那样去遍历目标元素之前的所有元素。

        队列的声明是使用带有美元符号的下标,[$]。队列元素的编号从0到$。注意队列的常量(literal)只有大括号而没有数组常量中开头的单引号。

        SV 会分配额外的空间以便你能够快速插入新元素。当元素增加到超过原有空间的容量时, SystemVerilg 会自动分配更多的空间。其好处是,你可以扩大或缩小队列,但不用像动态数组那样在性能上付出很大代价,SV会随时记录闲置的空间。注意不用对队列使用构造函数 new[]。

举个栗子:

int jj = 1,
q2[$] = {3,4},
q[$] = {0,2,5};

initial begin

    q.insert(1,jj); //在索引1的位置插入jj
    $display("1:q[$] = %0p",q); //{0,1,2,5}

    q.delete(1); //删除索引1的元素
    $display("1:q[$] = %0p",q); //{0,2,5}

    //q.insert(3,q2); //在索引3的位置插入q2,但不是所有仿真器都支持

end

运行结果:

 ​​​​​​​        

        队列中的元素是连续存放的,所以在队列的前面或后面存取数据非常方便。无论队列有多大,这种操作所耗费的时间都是一样的。在队列中间增加或删除元素需要对已经存在的数据进行搬移以便腾出空间。相应操作所耗费的时间会随着队列的大小线性增加。你可以把定宽或动态数组的值复制给队列。

        所以,下面的操作执行速度很快:


q.push_front(6); //在队列前面插入6
$display("1:q[$] = %0p",q); //{6,0,2,5}

jj = q.pop_back; //取出队列最后一个元素
$display("2:jj = %0d",jj); //5

q.push_back(8); //在队列末尾插入8
$display("3:q[$] = %0p",q); //{6,0,2,8}

jj = q.pop_front; //取出队列第一个元素
$display("4:jj = %0d",jj); //6

foreach(q[i])
    $display(q[i]);

q.delete; //删除队列

运行结果:

 

        注:队前插入和队末插入可以使用等效语句:

//在队列前面插入6

语句1:q.push_front(6);

语句2:q={6,q};

//在队列末尾插入8

语句1:q.push_back(8);

语句2:q={q,8};

二、枚举

        枚举类型,对系列有含义的整型变量进行有意义名称的定义,可增强代码的可读性。这种类型的变量,主要还是定义应用,内置函数用得较少。有个经常说到的问题是整型变量与枚举变量之间的转换,枚举转换成整型可用直接赋值反过来则不行,需要用case函数进行强制转换,避免越界。

最简单的枚举类型声明如下:

enum {RED,BLUE,GREEN}color;

可以使用typedef创建一个署名的枚举类型,有利于声明更多新变量。

//创建代表0,1,2的数据类型

typedef enum{INIT,DECODE,IDLE}fsmstate_e;

fsmstate_e pstate, nstate;//声明自定义类型变量

initial begin

    case(pstate)

        IDLE:nstate=INIT;//数据赋值

        INIT:nstate=DECODE;

        default:nstate=IDLE;

    endcase

    $display("Next state is %s",nstate. name());//显示状态的符号名

end

当pstate = DECODE时,运行结果如下:

 

SV提供的一些可以遍历枚举类型的函数:

名称

描述

first()

返回第一个枚举常量

last()

返回最后一个枚举常量

next()

返回下一个枚举常量

next(N)

返回以后第N个枚举常量

prev()

返回前一个枚举常量

prev(N)

返回以前第N个枚举常量

遍历枚举成员时,使用do...while

typedef enum{RED,BLUE,GREEN}color_e;

color_e color;

color=color. first;

do

    begin

        $display("Color=%0d/%s", color, color. name);

        color=color. next;

    end

 while(color!=color. first);//环形绕回时即完成

运行结果如下:

 

枚举类型的转换

        枚举类型的缺省类型为双态int。可以使用简单的复制表达式把枚举变量的值直接赋值给非枚举变量如int。反过来则不能简单的直接赋值,因为会存在越界的情况。

举个栗子:

typedef  enum{RED ,BLUE, GREEN}color_e;
color_e c1,c2;
int c;

//枚举转为整型:

c1 = BLUE;
c = c1; //直接赋值 c=1;

//整型转枚举:

c++; // c= 2;
if(!$cast(c1,c))
    $display (“Cast failed for c = %0d”,c);
$display (“c1 is %0d/%s", c1, c1.name);

c++; // c= 3;
c2=color_e’(c); //强制类型转换 ;越界了
$display("c2 is %0d/%s", c2, c2.name);

运行结果如下:

 

        注意,这里使用了强制类型转换,type(val),该转换不做类型检查;另外一种是把$cast当做函数使用,将右边的值赋给左边,如果赋值成功,则$cast()返回1。如果因为数值越界导致赋值失败,则不进行赋值,函数返回0。

三、字符串

        SV使用string类型来保存长度可变的字符串。单个字符串是byte类型。

        字符串在验证平台中主要使用方式,定义,拼接(与变量)以及提取和格式化打印,最终目标还是打印平台的仿真信息

方法

描述

getc(N)

返回位置N上的字节

toupper

返回一个全大写的字符串

tolower

返回一个全小写的字符串

putc(M,C)

把字节C写到字符串的M位上,M在长度范围内

substr(start,end)

提取start到end之间的所有字节

{}

字符串拼接

举个栗子:

string s;

initial begin

    s = "IEEE ";

    $display(s.getc(0)); //73 'I'

    $display(s.tolower()); //ieee

    s.putc(s.len()-1,"-"); //IEEE-

    s={s,"P1800"}; //IEEE-P1800

    $display(s.substr(2,5)); //EE-P

end

运行结果如下:

 

四、其他

其他数据类型不是很常用,简单认识一下。

typedef重定义

typedef 已有类型名 新类型名;//其实就是换个命名

链表

SV支持链表的数据类型,但是不推荐使用。使用队列替代。


http://www.niftyadmin.cn/n/1076115.html

相关文章

mybatis generator 生成javabean自定义类型转换

因为默认mybatis generator自动生成的,带小数的都转成了bigdecimal了,而且长度不同的整数转成了不同的类型。 但是我想要带小数的转成double,整数转成integer。 所有自定义类型转换 代码如下: /** Copyright 2005 The Apache Sof…

【SystemVerilog】SV对设计意图的细化always和unique/priority

always、always_comb、always_latch、always_ff; unique /priority case ; unique /priority if...else ; 一、SV中的always 在Verilog中,设计组合逻辑和时序逻辑时,都要用到always: always (*)begin…

建造者模式——笔记

建造者模式 概念 将一个复杂对象的构建层与其表示层相互分离,同样的构造过程可以采用不同的表示。使用及与工厂模式的区别 比如说我们在网站上给别人推送一些简历的时候,我们就需要隐藏一些求职者的信息来获取利益,这时我们就需要抽象提取应聘…

第4章 用position定位方法实现自适应效果的三列布局

第4章 用position定位方法实现自适应效果的三列布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>第4章 用position定位方法实现自适应效果的三列布局</title><style type"text/css&…

PE文件格式分析

void pe_print(){ IMAGE_DOS_HEADER myDosHeader; IMAGE_FILE_HEADER myFileHeader; int nSectionCount;//PE文件ection数目 LONG e_lfanew;//为DOS头部的偏移 FILE *fp; if(fpfopen("e:\\1000.exe","rb")) //打开一个文件 { …

Google kickstart 2017 Round A

Problem A. Square Counting 数由格点组成的所有正方形个数&#xff0c; 正方形的边可以不和坐标轴平行。 对于每个由个点组成的正方形&#xff0c;存在一个最小的格点正方形&#xff0c;这个正方形的边平行于坐标轴。 考虑边长为k的平行于坐标轴的格点正方形&#xff0c;它正好…

FreeType 管理字形

转自&#xff1a;http://blog.csdn.net/hgl868/article/details/7254687 1.字形度量 顾名思义&#xff0c;字形度量是对应每一个字形的特定距离&#xff0c;以此描述如何对文本排版。通常一个字形有两个度量集&#xff1a;用来排版水平文本排列的字形&#xff08;拉丁文、西里尔…

Expressions and Statement

JavaScript 两个最重要的概念表达式和语句 表达式概念&#xff1a;An expression is a phrase of JavaScript that a JavaScript interpreter can evaluate to produce a a value. 表达式的分类: 1.Primary Expressions 1 "hi word"2 /pattern/3 4 //some of JavaScr…