Systemverilog笔记 过程语句和子程序

第三章 过程语句和子程序

1.过程语句

sv吸收了C++的一些特性,包括了break以及continue语句等。

//for循环语句以及do……while语句
initial begin:example             //可以给这个initial起一个编号名,这里叫example
    integer a[10],sum,j;
    
    for(int i=0;i<10;i++)        //为每一个数组元素赋值
        a[i]=i;
    
    sum=0;    
    j=9;
    do
        sum+=a[j]               //将数组的每一个元素相加并求和
    while(j--);
    
    $display("Sum is %4d",sum);
end :example

读取文件的例子

initial begin
	bit[127:0] cmd;
	int file,c;
	
	file=$fopen("a.txt"."r");
	while(!$feof(file)) begin
    c=$fscanf(file,"%s",cmd); //cmd读取一行数据
	case(cmd)
		"": continue;         //读出来空行就继续读
        "done": break;        //读出来done就结束while循环
	endcase
    end
	$fclose(file);
end

2.任务task和函数function

verilogsystemverilog
task(任务)可以消耗时间(可以用#100)同v
function(函数)不可以调用task,不能有时延语句和阻塞语句(不能用#100,wait(),posedge等语句),换句话说,任务可以消耗时间但是函数不可以允许函数调用函数,但是只能用在(fork…join_none语句生成的线程中调用)
//如果需要一个不消耗时间的任务,可以用function void函数
function void print_state(…);
	$display("@%0t:state=%s",$time,cur_state.name());
endfunction

//如果想调用函数并忽略返回值,可以使用void'(在部分仿真器中可用)
void'($fscanf(file,"%d",i));

在sv中,task和function的定义都不再需要使用begin…end(显然V中需要)。

3.子程序

3.1子程序参数

在这里插入图片描述

​ 众所周知,在一个C语言的函数程序中,不仅可以复制变量,也可以通过指针来直接修改变量本身的大小,在sv中也采用了这种指针技术,可以进行引用(ref)而不是复制。现在,可以把数组传递给函数来直接修改数组,这相当于给了一个指向数组的指针。

//使用ref和const来传递数组
function void print_checksum(const ref bit[31:0] a[]);
	bit [31:0] checksum = 0;
	for(int i=0;i<a.size();i++)
		checksum^=a[i];
	$display("The array checksum is %0d",checksum);
endfunction
//这里的const用来保证不修改指针对应数组的值大小
//使用ref可以保证修改变量并且修改结果对调用函数可见
//在sv中也可以不用ref来进行数组传递,但是这样操作实际上就是把数组复制到函数所在的局部变量堆栈中

函数也可以默认使用缺省值

function void print_state(input int low=0,input int high=-1);
endfunction

print_state();     //low=0,high=-1
print_state(1,3);  //low=1,high=3
print_state(,2);   //low=0,high=2

采用端口进行参数传递,相信正常人应该都知道v中的例化方法是采用 .a(a)这种模式,如果函数参数过多也可以采用端口传递。

function void print_state(input int a=1,b=2,c=3,d=4);
endfunction

print_state();         //1,2,3,4     默认缺省值
print_state(5,6,7,8);  //5,6,7,8     指定所有值
print_state(.a(2));    //2,2,3,4     端口模式
print_state(.a(2),3);    //2,3,3,4   混合模式

在缺省的情况下参数的类型是与前一个参数类型相同的。

task s(ref int a[10],int b,c);
//由于b跟c没有指明方向,会默认为ref,但是ref显然对int无效,需要修改为下面这样
task s(ref int a[10],input int b,c);

3.2 子程序返回

sv中可以在task和function中使用return语句。

返回数组的三种方式

//1.定义一个数组类型,并返回这个新的数据类型
typedef int my_arrray[5];  //定义一个类型,它是一个五个元素的数组
my_array f5;

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

initial begin
	f5=init(5);
	foreach(f5[i])
		$display("f5[%0d]=%0d",i,f5[i]);
end

//2.用ref参考来返回数组
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])
        $display("fa[%0d]=%0d",i,fa[i]);
end

//3.将数组包装到一个类中,然后返回对象的句柄 (待补充)

4.局部数据存储

4.1自动存取

​ 在verilog中对同一个task多次调用会因为局部变量使用共享的局部静态变量而造成覆盖,所以需要使用以下语句,强迫堆栈来存取。

program automatic test;

endprogram

4.2变量初始化

​ 局部静态变量其实在仿真前就已经赋值了,而不是在begin以及end语句中再进行赋值。

解决方法1 automatic

program automatic test;

endprogram

解决方法2 将声明和初始化拆开

logic [31:0] local_addr;

local_addr = addr<<2;

5.时间值

//$time和$realtime都能返回时间,但是前者为整数,后者为小数

//time不能保存小数时延,如果需要小数时延,需要使用real
`timescale 1ps/1ps
module ps;
	initial begin
		real a = 800 fs;
		time b = 800 fs;
		$display("%t",a);   //800fs
		$display("%t",b);   //1000fs,time会四舍五入
end
endmodule

//timeuint(单位),timeprecision(最小精度)
//$timeformat(时间标度,小数点后位数,后缀字符串,显示数值的宽度) -9为ns,-12为ps
module time;
    timeuint 1ns;
    timeprecision 1ps;
    initial begin
        $timeformat(-9,3,"ns",8);
        #1 $display("%t",$realtime);  //1.000ns;
        #2ns $display("%t",$realtime);  //3.000ns;
        #0.1ns $display("%t",$realtime);  //3.100ns;
        #41ps $display("%t",$realtime);  //3.141ns;
        end
endmodule
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SystemVerilog是一种硬件描述语言(HDL),用于设计和验证数字电路。SystemVerilog具有丰富的特性,适用于各种设计和验证任务。以下是SystemVerilog入门笔记的一些重点内容。 首先,了解SystemVerilog的基本语法是很重要的。SystemVerilog继承了Verilog的语法,同时加入了一些额外的特性,如数据类型、类和接口等。熟悉这些语法规则对于编写有效的代码至关重要。 其次,了解模块和端口的概念。SystemVerilog中的模块是最基本的构建单元,而端口则是模块与外部环境之间的接口。了解如何定义和使用模块和端口是编写可重用代码的关键。 另外,掌握数据类型和运算符是必不可少的。SystemVerilog支持多种数据类型,如整数、浮点数、逻辑值等,同时也提供了丰富的运算符,如加法、减法、逻辑运算符等。这些知识对于设计和验证数字电路非常重要。 此外,了解时序控制和并发控制是必要的。SystemVerilog提供了多种时序控制和并发控制的语法和特性,如always块、initial块和fork/join语句等。掌握这些知识对于设计复杂的数字电路至关重要。 最后,了解Verilog验证中的一些基本概念也是很重要的。例如,了解如何使用assert语句进行断言检查、如何使用coverage语句进行覆盖率分析等。 总之,SystemVerilog入门需要掌握其基本语法、模块和端口、数据类型和运算符、时序控制和并发控制,以及一些基本的验证概念。这些知识是成为一名合格的SystemVerilog工程师所必备的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

jun_luo_yu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值