sv过程语句和子程序

写在前面:类似c语言,多练习就好。

sv过程语句

与verilog相比,SV加入了与C/C++类似的自增自减操作符、continue、return等语句。

 实例:自增自减操作符、for、while

//systemverilog绿皮书
//例题3.1 新的过程语句和操作符
//仿真结果是45
module procedure();
//自增自减操作符
//i++和i--是先把值赋给下一语句,然后+1或-1
//++i和--i是先+1或-1,然后把值赋给下一语句
initial
	begin:example//此处的:example可以不写
	integer array[10],sum,j;
	
	//在for语句中声明i
	for (int i=0;i<10;i++)//i递增
		array[i]=i;	
	
		
	//把数组里的元素相加
	sum=array[9];
	j=8;
	do                 //do...wahile循环  
		sum+=array[j]; //累加
	while(j--);        //判断j=0是否成立
	
	$display("sum=%4d",sum);//%4d指定位宽,之前遇到的%0d就是打印最小位宽
	end:example
	
endmodule
  •  自增自减操作符
  • i++和i--是先把值赋给下一语句,然后+1或-1
  • ++i和--i是先+1或-1,然后把值赋给下一语句

 

实例:逻辑比较操作符

 

//逻辑比较操作符
//E课网

module wild_equality_operator();
bit [7:0] data =8'hFF;//f代表4位的1,ff代表8位全1
initial begin
	//Compare with wild equality
	//if (data=?= 8'b1xxx_z1xz) begin
	if (data ==? 8'b1xxx_z1xz) begin
	$display ("Data %b matches with %b", data, 8'b1xxx_z1xz);
	end
	//Compare with wild non-equality
	//if (data!?=8'blxxx 21x0) begin
	if (data!=? 8'b1xxx_z1x0) begin
	$display ("Data %b does not matches with %b", data, 8'b1xxx_z1xz);
	end
	#1 $finish;
end

endmodule

 仿真结果如下:


Data 11111111 matches with 1xxxz1xz
Data 11111111 does not matches with 1xxxz1xz
$finish called from file "wild_equality_operator.sv", line 17.
$finish at simulation time       
  • 等于==,不等于!=

逻辑真为1,逻辑假为0

如果比较的值中存在x或z,则逻辑值为1'bx

  • 全等===,不全等!==

完全匹配四种状态值:0,1,x,z

  • 通配符逻辑比较

匹配等==?匹配不等 !=?

按位比较,把x和z值当做匹配值,仅仅把右侧操作数中的z和x当做屏蔽符号

  • A=010z;
    B=0101;
    
    A==?B;逻辑值:未知1'bx   //左侧操作数含有z,不能做匹配值
    B==?A;逻辑值:1'b1      //右侧操作数含有z,可以匹配左侧的1

inside

 

inside可以匹配一组数据范围内的任何一个数值

logic [2:0] a;
if ((a==3'b001)||(a==3'b010)||(a==3'b100));
等价于
logic [2:0] a;
if (a inside {3'b001,3'b010,3'b100});

变量类型转换

变量类型转换

type'(expression)

 

  • Verilog使用赋值语句进行变量类型转换

阻塞赋值:=

非阻塞赋值:<=

  •  Systemverilog增加了变量类型转换符

变量类型转换符可以在任何时刻对表达式进行类型转換

而不像 verilog-样只能发生在赋值语句中

longint a, y;
real r;//real 64位浮点数?
y=a +longint'(r**3);
  •  $cast强制类型转换
//$cast强制类型转换
//E课网
module cast();
typedef enum {IDLE, SFD, PREAMBLE,DATA, FCS, EFD} eth_state;
eth_state fsm;

initial begin
#5 fsm= IDLE;
$display("@%0dns Current value of FSM:  %s\n",$time, get_name(fsm));
#5 fsm=SFD;
$display ("@%0dns  Current value of FSM: %s\n",$time, get_name(fsm));

#1 $cast(fsm, 1+2);
$display ("@%0dns  Current value of FSM: %s\n",$time, get_name(fsm));
//Below Line should give compile error
//fsm =2+1;
end

变量位宽转换

  • 表达式转換成较小位宽时,左侧的比特位删除
  • 表达式转換成较大位宽时,左侧的比特位被扩充
  • logic [15: 0] a,b,C,sum;
    logic carry;
    sum=a+16'(5);          //操作数位宽扩展
    {carry, sum}=17 '(a+3);//表达式结果位宽扩展
    sum=a+16'(b-2)/c;      //中间结果位宽扩展

     

变量符号位转换:

  • signed'(expression)
  • unsigned'(expression)
  • sum=signed'(a)+signed'(b);//操作数符号位转换
  • if(unsigned'(a-b)<=5);//表达式中间结果转换

 

for循环语句

  •  Verilog中循环变量必须在for语句之外声明

当前循环与其它语句相互影响

  • ◆System Verilog可以在for循环内部声明循环变量

每个变量都为本地的唯一的变量,所以外部使用的相同名字的变量不会相互影响

本地循环变量是自动化的( automatic)

for循环内部声明的本地变量在循环语句之外就不存在了

//for循环句中i的和外部的i是具有相同的名字,但是两者的作用范围不同
int i;
always @(posedge clock)begin
for( inti=l: i<=1024, i=i+1)
//balabala
end

 for循环语句控制/跳转

continue

  • 只能用于循环语句
  • 结束本次循环,继续下一次循环

break

  • 只能用于循环语句
  • 破坏循环,跳岀循环,不在执行循环语句

return

  • 可以用于循环语句,结束循环
  • 也可以用于task和 Function,结束task或 function

 

 实例:continue_loop.sv

//continue_loop.sv
//E课网
module continue_loop();
initial begin
	for (int i=0;i< 10;i++)begin
		if((i>=5)&&(i<8)) begin
			$display ("Continue with next interation");
			continue;
		end
		#1 $display ("Current value of i=%g",i);
	end
	#1 $finish;
end
endmodule

仿真结果如下: 

Compiler version I-2014.03; Runtime version I-2014.03;  Aug 15 09:21 2020
Current value of i=0
Current value of i=1
Current value of i=2
Current value of i=3
Current value of i=4
Continue with next interation
Continue with next interation
Continue with next interation
Current value of i=8
Current value of i=9
$finish called from file "continue_loop.sv", line 12.
$finish at simulation time                   11
           V C S   S i m u l a t i o n   R e p o r t 

 实例:break_loop.sv

//break_loop.sv
//E课网
module break_loop();
initial begin
	for (int i=0;i< 10;i++)begin
		#1 $display ("Current value of i=%g",i);
		if(i==5) begin
			$display ("Coming out of for loop");
			break;
		end	
	end
	#1 $finish;
end
endmodule

 仿真结果如下:

Compiler version I-2014.03; Runtime version I-2014.03;  Aug 15 09:37 2020
Current value of i=0
Current value of i=1
Current value of i=2
Current value of i=3
Current value of i=4
Current value of i=5
Coming out of for loop
$finish called from file "break_loop.sv", line 12.
$finish at simulation time                    7
           V C S   S i m u l a t i o n   R e p o r t 

实例:return_fuction.sv

//return_fuction.sv
//E课网

module return_fuction();
initial begin
	printI();
	#1 $finish;
end

function void printI;
begin
	for(int i=0;i<10;i++)begin
		if(i>5)begin
			return;//no value returned
		end
		$display("Current value of i = %g",i);
	end
end

endfunction
endmodule

 仿真结果如下(与上一个一样):

Compiler version I-2014.03; Runtime version I-2014.03;  Aug 15 09:48 2020
Current value of i = 0
Current value of i = 1
Current value of i = 2
Current value of i = 3
Current value of i = 4
Current value of i = 5
$finish called from file "return_fuction.sv", line 7.
$finish at simulation time                    1
           V C S   S i m u l a t i o n   R e p o r t 

 实例:return_value_fuction.sv

//return_value_fuction.sv
//E课网

module return_value_fuction();
initial begin
	$display("Value returnded from function =%g",printI());
	#1 $finish;
end

function int printI;
begin
	for(int i=0;i<10;i++)begin
		if(i>=5)begin
			return i ;// value returned
		end
		$display("Current value of i = %g",i);
	end
end
endfunction
endmodule

 仿真结果如下(为什么会打印两次0-5?):

Current value of i = 0
Current value of i = 1
Current value of i = 2
Current value of i = 3
Current value of i = 4
Current value of i = 5
Current value of i = 0
Current value of i = 1
Current value of i = 2
Current value of i = 3
Current value of i = 4
Value returnded from function =5
$finish called from file "return_fuction.sv", line 7.

预期的效果是这样的呀! 

do-while循环

 

  • Verilog中的whil循环不一定执行

    如果第一次循环表达式的值为假,则循环语句不会执行

  • System Verilog增加了do… while循环语句(类似于C语言)

    至少行一次循环语句

    在循环语句的最后判断循环变量

case语句 

case:

casex:不关心x和z

casez:不关心z

 

 

taskf和function

function

 

  • 函数执行的时候不消耗仿真时间
  • 函数中不能有控制仿真时间的语句

不能有仿真时间延迟:#100(`timecase 1ns/10ps)

不能有阻塞语句:@( (posedge clock)或者 wait(ready)

不能调用task(其实,如果task中没有时间延迟、阻塞语句,应该可以调用

  • void function没有返回值

Verilog function必须有一个返回值

task

  • task含有 Input、 outpute或者inout语句
  • task消耗仿真时间

延迟:#20

时钟周期:@( posedge clock)

事件: event

这么理解,就是task可以消耗时间,但是function不消耗时间,所以,function不能调用包含消耗时间的task,task可以调用function,

 

 

写在最后:task和function最重要吧

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杰之行

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

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

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

打赏作者

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

抵扣说明:

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

余额充值