SystemVerilog Verification Test Platform Writing Guide Chapter 3 Process Statements and Subroutines

SystemVerilog在Task and functionA lot of improvements have been made to make it closer to the C language, so that the writing of code becomes easier, especially in the processing of parameter passing.

3.1 Procedural statements
SystemVerilog references many operators and statements from C and C ++. Here are a few brief introductions.
1) For loop, define the loop variable in the for loop, its scope of action is limited to the inside of the loop, thus helping to avoid some code loopholes.
for (int i = 0; i <10; i ++)
2) Auto-increment / auto-decrement, ++ / –, can be used as prefix or suffix.
3) Identifier, you can use the identifier in the begin or fork statement, then put the same label in the corresponding end or join statement. Similarly, you can also put identifiers in statements such as endmodule, endtask, and endfunction.

initial
	begin:example
		......
	end:example

4) The loop function, compared to Verilog, the loop function adds continue, which is used to skip the remaining statements in the loop and go directly to the next round; break is added to terminate and jump out of the loop.

3.2 Tasks, functions and void functions
In Verilog, there is a clear difference between task tasks and function functions, of whichTasks can consume time and functions cannot. SystemVerilog allows function call tasks, but can only be called in threads generated by fork ... join_none statements.
If there is oneNot time consumingFor SystemVerilog tasks, you should define it as a void function, which has no return value.

function void print_state(........);
	......
endfunction

3.3 Remove begin ... end in subprograms
In SystemVerilog, begin ... end becomes optional, because the keywords task ... endtask and function ... endfunction are enough to define the boundaries of these subprograms.

3.4 Subroutine parameters
SystemVerilog's many improvements to subroutines make the declaration of parameters more convenient, and also expand the way parameters are passed.
3.4.1 C-style subroutine parameters
In Verilog, for some parametersMake two declarations, one for direction declaration and one for type declaration

task my_task;
	output [31:0] x;
	reg   [31:0] x;
	input    y;
	......
endtask

inSystemVerilogIn, you can adopt a concise C language style, merge types and directions, and declare at the beginning,Note that the common data type logic must be used

task my_task(output logic[31:0] x,
					input logic y);
			......
endtask

3.4.2 Parameter direction of
subprogram parametersThe default value type and direction is 1 bit wide logic input

task T3;
	input a,b;
	......
endtask

Parameters a and b are logic inputs with a 1-bit width.
3.4.3 Advanced parameter types
Verilog handles parameters very simply: copy the value of input / inout to the local variable at the beginning of the subprogram, and copy the value of output / inout when the subprogram exits.
In SystemVerilog, the method of passing parameters can be specified as a reference rather than a copy. useref parameter type can pass the array to the subroutine

function void print_check(const ref bit[31:0] a[]);
	bit [31:0] checksum=0;
	for(int i=0; i<a.size();i++)
	check^=a[i];
endfunction

The ref parameter can only be used in subprograms with automatic storage. If you specify the automatic attribute for a program or module, the entire subprogram is automatically stored.
The const modifier determines that the subroutine cannot modify the value of the array.
Variables can be modified in the task and the results of the modification are always visible to the calling function.
3.4.4 Default values ​​of parameters
In SystemVerilog, you can specify a default value for the parameter. If you do not specify the parameter when calling, the default value is used.

function void print_check(ref bit[31:0] a[],
										input bit[31:0] low=0,
										input int high =-1);
	bit[31:0] check=0;
	if (high=-1||high>a.size())
	high=a.size()-1;
	for(int i=0;i<=high;i++)
		checksum+=a[i];
endfunction

When calling a function, there are several ways:

print_check(a);//a[0:size()-1]中所有元素的校验和——缺省情况
print_check(a,2,4);//a[2:4]中所有元素的校验和
print_check(a,,1);//a[0:1]中所有元素的校验和
print_check(a,2);//a[2:size()-1]从2开始
print_check( );//编译错误:a没有缺省值

3.4.5 Parameter passing by name
Similar to the port of the module, a subset can be specified by specifying the subprogram parameter name by using a port-like syntax.

task many(input int a=1,b=2,c=3,d=4);
	.......
endtask

The form of function call:

many(6,7,8,9); //6 7 8 9指定所有值
many();//采用1,2,3,4使用缺省值
many(.c(5));//1,2,5,4只指定c
many(,6,.d(8));//1,6,3,8混合方式

3.4.6 Common code errors
By default, the type of the parameter is the same as its previous parameter, and the default type of the first parameter is single-bit input

task sticky(int a,b);//a、b为两个整型的输入。
task sticky(ref int array[50],int a,b);//默认a、b的方向为ref 错误的方向类型
task sticky(ref int array[50],input int a, b);//a、b为整型输入

3.5 Return of subroutine
3.5.1 Return statement
SystemVerilog adds return statement, which makes the flow control of subroutine more convenient. When return is executed, you can return directly without executing the code below.
3.5.2 Return an array from a function In
SystemVerilog, a function can return an array in various ways.
1) Define an array type, and then use the type in the function declaration.

typedef  int fixed_array5[5];
fixed_array5  f5;

function fixed_array5 init(int start);
	foreach(init[i])
		init[i]=i+start;
endfunction

initial 
begin
	f5=init(5);
	foreach(f5[i])
end

2) Pass the array parameters by reference. The easiest way is to pass the array to the function in the form of ref parameters. Obviously, this method is the best form of understanding.

function void init(ref int f[5], input int start);
	foreach(f[i])
		f[i]=i+start;
endfunction
int fa[5];
initial
begin
	init(fa,5);
	foreach(fa[i])
end

3.6 Local data storage
For injection into a hardware engineer, all described objects in Verilog language are static, especially for subprogram parameters and local variables are stored in a fixed location, rather than stored in other programming languages Within the stack area. There is no corresponding chip implementation for dynamic codes such as recursive subprograms, but in the verification process, these dynamic intermediate results have an important impact, so how can we model them?
3.6.1 Automatic storage
in Verilog, if you try toCall the same task in multiple placesBecause the local variables in the task will use the shared static storage area, these local variables will be used between different threads. At this time, you can specify tasks, functions, modules to use automatic storage, thereby forcing the stack area to store local variables.
In SystemVerilog, subroutines in modules and program blocks still use static storage by default. If automatic storage is used, the automatic keyword must be added to the program statement.In this case, each call uses a different storage space

program automatic test;

3.6.2 Initialization of variables
We hope to perform the following operations after a period of time in the simulation. Give two examples, let everyone experience the initialization of variables.

logic[7:0] local_addr=addr<<2;

For static variables, it will have initial values ​​at the beginning of the simulation. It can be modified to automatically store.

logic[7:0] local_addr;
local_addr=addr<<2;

Separate declaration and initialization, so that you can meet the requirements of the problem.

3.7 Time value
3.7.1 Describe time unit and precision
(1) Method one, 'timescale
(2) Method two, timeunit and timeprecision
3.7.2 Time parameter
a. $ Timeformat (Time scale (-9 represents ns, -12 represents ps), the data precision after the decimal point, the suffix character after the time value, the minimum width of the displayed value)
$ timeformat (-9,3, "ns", 8); //1.000ns
b. $ time
according to the time precision of the module An integer that requires rounding.
c. $ realtime
is a complete real number with a decimal part.

`timescale 1ps/1ps
module ps;
	initial 
	begin
		real rdelay=800fs;    //   0.8ps 以0.800存储
		time tdelay=800fs;   // 1ps舍入后得到1
		$timeformat(-15,0,“fs”,5);
		#rdelay                    //1ps,在作延时时,去时间精度1ps
		$display("%t",rdelay);  // "800fs"
		#tdelay                     //1ps 再次延时1ps
		$display("%t",tdelay);  // "1000fs"
	end
endmodule
Published 38 original articles · Like 29 · Visits 10,000+

Guess you like

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