SystemVerilog笔记(持续更新中)

第一章 数据类型

2.1 内建数据类型

   对于四值逻辑:
    未初始化的变量=x;
    未初始化的线网=z
    对于二值逻辑:
    未初始化的变量=0;
    未初始化的线网=0

2.1.1 逻辑(logic)类型

logic类型是在reg类型的基础上改进的。任何使用线网的地方都可以使用logic,但是要求logic不能有多个结构性的驱动,例如在对双向总线建模的时候,此时需要适用线网类型。

module logic_data_type(input logic rst_h);
parameter CYCLE=20;
logic1,q_l,d,clk,rst_l;
initial begin
	clk=0;
	forever #(CLCLE/2) clk=~clk;
end

assign rst_l=~rst_l;
not n1(q_l,q);
my_dff d1(q,d,clk,rst_l);

endmodule	

由于logic类型只能有一个驱动,所以可以使用它来查找网单中的漏洞。把所有信号都声明为logic而不是reg或wire,如果存在多个驱动,那么编译时就会出现错误。

2.1.2 双状态数据类型

相比四个状态数据类型,SV引入的爽状态数据类型有利于提高仿真器的性能并减少内存使用。
双状态数据类型:bit(无符号)、byte、shortint和longint:

//双状态
bit b;			//单比特
bit [31:] 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 t;						//双精度浮点数						

使用$isunknown操作符可以在表达式任意位置出现X或Z时返回1。
例2.3 对四状态值检查

if($isunknown(inport)==1)
	$dilplay("@%0t:4-state value detected n iport %b",$time,inport);

2.2 定宽数组

2.2.1 定宽数组的声明和初始化

因为几乎所有的数组都使用0作为索引霞姐,所以SV允许只给出数组的宽度的便捷声明方式:

//都表示16个整数
int lo_hi[0:15];
int lo_hi[16];

创建多维定宽数组:

int array2 [0:7][0:3];			//完整声明
int array3	[8][3];				//紧凑声明
int array2 [7][3]=1;			//最后一个元素赋值

2.2.2 常量数组

常量数组的使用如下:

int ascend [4] ='{0,1,2,3};			//对元素进行初始化
int descend [5];

descend ='{4,3,2,1,0};					//为五个元素赋值
descend [0:2] ='{5,6,4};
ascend ={4{8}};							//前四个值都是8
descent ='{7,9,default:1}				//{7,9,1,1,1}

2.2.3 基本的数组操作——for和foreach

foreach循环中,只需要在指定数组名并在其后面的放括号中给出索引变量,SV会自动遍历数组中的元素。

initial begin
	bit[31:0] src[5],dst[5];
	for(int 0=0;i<$size(src);i++)	//$size返回数组的宽度
		src[i]=i;
	foreach (dst[j])
	dst[j]=src[j]*2;
end

在多维数组中使用foreach的语法foreach 数组名[i,j]。

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

例2.13 数组的赋值和比较操作

initial begin
	bit [3:] src[5] ='{0,1,2,3,4},
			   dst[5]='{5,4,3,2,1};
	if(src==dst)
		$display("src==dst");
	else
		$display("src!=dst");
	
	//把src所有元素复制给dst
	dst=src;

	//只改变一个元素的值
	src[0]=5;

	//所有元素的值是否相等
	$display("src[1:4] %s dst[1:4]",
			(src[1:4]==dst[1:4])?"==":"!=");
end

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

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

initial begin
	bit [31:0] src[5] ='{5{5}};
	$display (src[0],,			//'b101 或 'd5
			  src[0][0],,		//'b1
			  src[0][2:1]);		//'b10
end

2.2.6 合并数组

声明合并数组时,合并的位和数组大小作为数据类型的一部分必须在变量名前指定。数组大小定义的格式必须得是[msl:lsb],而不是[size]。如下:

例2.15 合并数组的声明和用法

bit [3:0][7:0] bytes;//将4个8bits的数据组装成32bit的数据
bytes=32'haabb_ccdd;			//或者bytes={8'haa,8'hbb,8'hcc,8'hdd},因为是一个整体所以要合并赋值
 
$display ("%h",bytes);			//打印整个数组,即32'haabb_ccdd;
$display ("%h",bytes[3]);		//最高byte,即8'haa
$display ("%b",bytes[3][7]);	//最高bit位,即8'haa=8'b1010_1010中的最高位1

在这里插入图片描述

note:位(比特位/bit/b)、字节(Byte)、字符和字的理解.

合并和非合并数组可以混合式还用。

例2.16 合并/非合并数组的声明和用法

bit [3:0] [7:0] barray[3];					//一个具有3个类似bytes元素的数组
bit [31:0] lw=32'h 01233_4567;				//字
bit [7:0][3:0] nibbles;						//合并数组
barray[0]=lw;
barray[0][3]=8'h01;
barray[0][1][6]=1'b1;
nibbles=barray[0];							//复制合并数组的元素值

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

当需要和标量进行相互转换时,使用合并数组会非常方便。例如,你可能需要以自己或字为单位对储存单元进行操作。任何数组类型都可以合并,包括动态数组。队列和关联数组。
如果需要等待数组中的变化,则必须使用合并数组。

2.3 动态数组

动态数组在声明时使用空的下标 [ ],使用时必须调用 new[位宽] 操作符来分配空间。
例2.17 使用动态数组

int dyn[],d2[];					//声明动态数组

initial begin
	dyn=new[5];					//分配5个元素			
	foreach(dyn[j]) dyn[j]=j;	//对元素进行初始化
	d2=dyn;
	d2[0]=5;
	$display(dyn[0],d2[0]);
	dyn=new[20](dyn); //分配20个整数值并复制,把dyn复制给新的dyn开始的5个元素,并释放dyn原有的所有内存
	dyn=new[100];				//分配100个新的整数值,不讲dyn原有的元素复制给新的dyn,而是直接释放

	dyn.delete();				//删除所有元素
end

还可以不声明数字元素个数而是直接赋值,这样系统会自动填写元素个数

bit [7:0] mask []='{....,....,....}

2.4 数组方法

  • 数组缩减方法:
    sum(求和)、product(积)、and、or、xor
  • 数组排序
    • .reverse() //反向排列
    • .sort() //生序排列
    • .rsort() //降序排列
    • .shuffle() //首位颠倒

其中reverse和shffle不能带with,作用于整个数组

  • 数组定位
    • find、find_index、find_first、find_last、find_first_index、find_last_index
    • min()、max()、unique、unique_index

2.5 如何选择数组

  • 灵活性

    • 动态数组>定宽数组;
    • 关联数组:由随机数据或地址产生的生疏分布索引的数组;
    • 队列:仿真过程元素数目变化很大的数组,记分板。
  • 存储器用量
    1、定宽与动态数组:

    • 元素数<1千:数组类型无所谓;
    • 1千<元素数 <1百万:定宽或动态数组;
    • 1百万<元素数:需优化算法。

2、队列:
- 存取效率比定宽或动态数组稍差,但在变化很大的应用中可抵消动态数组new的开销

3、动态数组:
- 兆字节的存储器建模

  • 速度
    • 定宽、动态数组>队列>关联数组;
    • 关联数组:存取速度最慢;
    • 队列:中间插入或删除元素导致元素搬移,程序会变慢。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芯动节奏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值