SystemVerilog Verification Test Platform Writing Guide Chapter 2 Data Types

2.6 Linked lists
SystemVerilog provides linked list data structures, but it should be avoided because the queues provided by SystemVerilog are more efficient and easier to use.
2.7 Array method
2.7.1 Array reduction method
The basic method of array reduction is to reduce an array to a value. The most commonly used method is to sum, in addition to product (multiplication) and (or) or (or) xor (exclusive OR), etc..
When performing array compression, it is particularly important to note that bit width is an issue.
Example 2.23 Sum of arrays

module test_enum();
bit on[10]; //单比特数组
int total;
initial begin                 
foreach(on[i]) 
on[i]=i; //on[i]的值为0或1
$display("on.sum=%0d",on.sum);  //on.sum是单比特无符号的数 打印出单比特和 on.sum=1
$display("on.sum=%0d",on.sum+32'd0);  //on.sum是32比特数 打印出32比特和 on.sum=5
//由于total是32比特变量,所以数组的和也是32比特变量
total=on.sum;
$display ("total=%0d",total); //total=5
//将数组和一个32比特数进行比较
if (on.sum>=32'd5) //条件成立
$display ("sum has 5 or more 1's'');
//使用带32比特有符号运算的with表达式
$display("int sum=%0d",on.sum with (int'(item))); //利用with来限定on.sum的数据类型,这是一种比较好用的方式
end     
endmodule

In SystemVerilog, $ urandom_range ($ size (array) -1) can be used to select a random element for fixed-width arrays, queues, dynamic arrays and associative arrays, and $ urandom_range (array.size ( )-1).

2.7.2 Array positioning method
Example 2.25 Array positioning method min, max, unique, find

module test_enum();
int f[6]={1,6,2,6,8,6},
d[]='{2,4,6,8,10},
q[$ ]={1,3,5,7},
tq[$];
initial
begin                 
tq=q.min();     //求最小值{1}
foreach(tq[i])
$display("min:tq[%0d]=%0d",i,tq[i]);
tq=q.max();    //求最大值{7}
foreach(tq[i])
$display("max:tq[%0d]=%0d",i,tq[i]);
        
tq=f.unique();   //求数组中唯一值的队列
foreach(tq[i])
$display("unique:tq[%0d]=%0d",i,tq[i]);
        
tq=d.find with (item>3);  //利用find函数做操作
foreach(tq[i])
$display("find:tq[%0d]=%0d",i,tq[i]);
tq.delete();     //等价的操作
foreach(d[i])
if(d[i]>3)
tq.push_back(d[i]);
foreach(tq[i])
$display("tq[%0d]=%0d",i,tq[i]);
        
tq=d.find_index with (item>3);  //输出的是index索引也就是第几位的值
foreach(tq[i])
$display("tq[%0d]=%0d",i,tq[i]);  
end     
endmodule

Note: item is called a repeating parameter, it represents a single element in the array, item is the default name, you can also specify another name. The following four cases are equivalent.

 tq=d.find_first with (item= =4);
 tq=d.find_first() with (item= =4);
 tq=d.find_first(item) with (item= =4);
 tq=d.find_first(x) with (x==4);

When the reduction method of an array is combined with the conditional statement with, the result of the sum operator is the number of times the conditional expression is true. Let us look at an example.

module test_enum();
	int count,
	total,
	d[]='{9,1,8,3,4,4};
	initial
	begin                 
	count=d.sum with (item>7);  //比较表达式返回0或1
	total=d.sum with ((item>7)*item);
	$display("count=%0d total=%0d",count,total);  //2,17 

	count=d.sum with (item<8);
	total=d.sum with (item<8?item:0);
	$display("count=%0d total=%0d",count,total);//4,12
	count=d.sum with (item==4);
	$display("count=%0d",count); //2
	end     
endmodule

2.7.3 Array arrangement
SystemVerilog has several ways to change the order of elements in an array.Including reverse, positive sequence, reverse sequence, random.
Example 2.29 Sorting an array

 int d[]='{9,1,8,3,4,4};
 d.reverse(); //反向'{4,4,3,8,1,9}
 d.sort();    //正序{1,3,4,4,8,9}
 d.rsort();   //逆序'{9,8,4,4,3,1}
 d.shuffle(); //随机'{9,4,3,8,1,4}

2.7.4 Using the array positioning method to build a scoreboard

2.8 Choosing storage types
In fact, the choice of data types is multi-faceted. We need to consider various aspects such as flexibility, memory usage, speed, sorting, and data structure. In our future applications, we will deeply understand each different The pros and cons of the data type.

2.9 Use typedef to create a new
type Define a new data type on top of the original data type. In order not to confuse this book, all user-defined types are suffixed with "_t".

 parameter opsize=8;
 typedef reg[opsize-1:0] opreg_t;
 opreg_t op_a,op_b;

 typedef bit[31:0] uint;
 typedef int unsigned uint;  //等价的两种方式

The new array definition is not obvious. You need to put the subscript of the array in the new array name.

typedef int fixed_array5[5];
fixed_array5 f5;
initial
begin
	foreach(f5[i])
		f5[i]=i;
end

2.10 Create user-defined structure
In SystemVerilog, we introduced the concept of data structure. A struct just organizes data together, just a collection of data.
2.10.1 Create new types using struct
struct can combine several variables together. We uniformly represent the new type created by struct with "_s".

typedef struct{bit[7:0] r, g,b;} pixel_s;
pixel_s my_pixel;

initial 
begin
	typedef struct {int a,
					byte b,
					shortint c;} my_struct_s;
	my_struct_s st='{32'haaaaaaaa,
					8'hbb,
					16'hcccc};
	$display("st=%x %x %x",st.a,st.b,st.c);
end

2.10.3 Create unions that can accommodate different types of unions
. Generally speaking, different types of data are placed in the same location. If you need to frequently read and write the same register in several different formats, the consortium is very useful. We agreed to suffix "_u".

typedef union { int i; real f;} num_u;
num_u un;
un.f=0.0; //把数值设为浮点形式

2.10.4 Merging structure
Let us describe the packed structure to save storage space through an example.

typedef struct packed {bit [7:0] r,g,b} pixel_p_s;
pixel_p_s my_pixel;

2.11 Type conversion
2.11.1 Static conversion
Static conversion does not check the conversion value. If it crosses the border, we can't detect it.
Basic conversion format: type '(val).
Example 2.41 Static conversion between plastic and real

int i;
real r;
i=int '(10.0-0.1); //转换是非强制的
r=real '(42);      //转换是非强制的

2.11.2 Dynamic conversion The
dynamic conversion function $ cast allows the check of out-of-bounds values. If it does not cross the boundary, it returns 1, otherwise it returns 0.
2.11.3 Stream operators
The stream operators >> and << are used to pack the subsequent data into a bit stream. >> is to turn the data from left to right into the data stream, << is to turn the data from right to left into the data stream.
Example 4.42 Basic stream operations

initial
begin
	int h;
	bit [7:0] b,
	g[4],
	j[4]='{8'ha,8'hb,8'hc,8'hd};
	bit [7:0] q,r,s,t;

	h={>>{j}};             //0a0b0c0d把数组打包成整型
	h={<<{j}};             //b030d050位倒序
	h={<<byte{j}};         //0d0c0b0a字节倒序
	b={<<{8'b0011_0101}};  //10101100位倒序
	b={<<4 {8'b0011_0101}};//0101_0011半字节倒序
	{>>{q,r,s,t}}=j;       //将j分散到四个字节变量里
	h={>>{t,s,r,q}};       //将四个字节集中到h里
end

2.12 Enumerated types
The simplest enumerated type declaration contains a list of constant names and one or more variables.
Use the built-in function name () to get the string corresponding to the value of the enumeration variable. We uniformly use the suffix "_e" to indicate the data type of the enumeration.
2.12.1 Define the enumeration value The
enumeration value defaults to an integer starting from 0, and you can define the enumeration value yourself. Usually when we refer to 0 for the enumeration constant, we can avoid some unnecessary errors.
2.12.2 Subroutines of enumeration type
(1) first () returns the first enumeration variable
(2) last () returns the last enumeration variable
(3) next () returns the next enumeration variable
(4) next (N) Return the Nth enumeration variable
(5) prev () Return the previous enumeration variable
(6) prev (N) Return the previous Nth enumeration variable to
traverse all enumeration members (note the enumeration type Value definition)
When the head or tail of the enumeration constant list is reached, the functions next and prev will automatically wrap around in a circular manner.
2.12.3 Conversion of enumerated types
The default type of enumeration type is two-state int.
The enumeration variable can be directly assigned to the variable int through a simple assignment expression.
It is not allowed to assign int directly to enumeration variables, this is out of consideration for out of bounds.
Example 2.51 Mutual assignment between integer and enumerated types

module test_enum();
typedef enum {RED,BLUE,GREEN} COLOR_E;
COLOR_E color,c2;
int c;

initial
begin                 
	color=BLUE; //赋一个已知的合法值
	c=color; //将枚举类型转换成整型
	c++; //整型递增
	if(!$ cast(color,c)) //将整型显示转换回枚举类型
	$ display("cast failed for c=%0d",c);
	$ display("color is %0d/%s",color,color.name);
	c++; //对于枚举类型已经越界
	c2=COLOR_E'(c); //不做类型检查
	$ display("c2 is %0d/%s",c2,c2.name);
	if(!$ cast(color,c))
	$display("cast failed for c=%0d",c);
	end
endmodule

result:

 #color is 2/GREEN
 #c2 is 3/
 #cast failed for c=3

$ cast (color, c) dynamically converts the int type to an enumerated type. If there is no cross-border return, 1 is returned, otherwise 0 is returned; within the bounds (0,1,2), 3 has already crossed the border.
2.13 The constant
const modifier is supported in SystemVerilog, allowing variable initialization when it is declared, but its value cannot be changed in the procedure code.
2.14 String
The string type in SystemVerilog can be used to save variable-length strings. A single byte is of type byte. Strings use dynamic storage, so don't worry about running out of storage space.
Example 2.53 String method

module test_enum();
string s;

initial
begin                 
	s="IEEE ";
	$display(s.getc(0));//显示:73('I')
	$display(s.tolower()); //显示:ieee

	s.putc(s.len()-1,"-"); //将空格变为'-'
	s={s,"P1800"}; //“IEEE-P1800”

	$ display(s.substr(2,5));    //显示:EE-P
	//创建临时字符串,注意格式
	my_log($psprintf("%s %5d",s,42));
end

	task my_log (string message);
	//把信息打印到日志里
	$ display("@%0t:%s",$time, message);
	endtask
endmodule

getc (N) returns the byte at position N
tolower () returns a lowercase string
putc (M, C) writes byte C to the M bit of the string, M must be between 0 and len Between lengths.
substr (start, end), read all characters from position start to end.

Published 38 original articles · Like 29 · Visits 10,000+

Guess you like

Origin blog.csdn.net/weixin_45270982/article/details/96707592