[SV]SystemVerilog学习笔记之过程块

                        SystemVerilog学习笔记(五)

 

一、System Verilog过程块、任务和函数

1.1.verilog通用目的always过程块(procedural block)(可综合)

   always过程块的综合指导方针:

  • 组合逻辑

1.关键词always后必须跟一个边沿敏感的事件控制(@符号)

2.事件控制的敏感表中不能包含posedge和negedge限定词

3.敏感表必须列出过程块的所有输入,所谓输入是指在该块读入并且在块外赋值的信号

4.过程块中不能包括其他的事件控制

5.所有在过程块中赋值的变量必须随所有可能的输入组合变化而更新

6.所有在此过程块赋值的变量不能在其他任何过程块再次赋值

  • 锁存逻辑

1.关键词always后必须跟一个边沿敏感的事件控制(@符号)

2.事件控制的敏感表中不能包含posedge和negedge限定词

3.敏感表必须列出过程块的所有输入,所谓输入是指在该块读入并且在块外赋值的信号

4.过程块中不能包括其他的事件控制

5.*过程块中赋值的变量至少有一个不能被某些输入条件更新

6.所有在此过程块赋值的变量不能在其他任何过程块再次赋值

  • 时序逻辑

1.关键词always后必须跟一个边沿敏感的事件控制(@符号)

2.事件控制的敏感表中必须包含posedge和negedge限定词

3.该过程块不能包含其他的事件控制

4.所有在过程块中赋值的变量不能在其他任何过程块再次赋值

 

1.2.system verilog特有的过程块(可综合)

  • 通过always_comb,always_latch,always_ff过程块相对于always可以更明确的反映设计意图

 

1.2.1.组合逻辑过程块(always_comb)

  • Eg.
always_comb
  if(!mode)          //mode在敏感list中
    y = a + b;       //a,b在敏感list中
  else
    y = a - b;

可以看出,always_comb块的后面不需要指明敏感列表。因为敏感表默认为所有被过程块读取(读取:出现在表达式右边或者作为条件语句的条件表达式中)并在块外赋值的信号。

  • always_comb过程块在所有initial和always过程块启动时,无论敏感变量是否发生变化,均会在仿真的0时刻自动触发
  • always_comb与always@*的区别:

always@*对过程块调用的函数中读取的信号不能推断为敏感变量

而always_comb的敏感列表包含函数读取的信号

 

1.2.2.锁存逻辑过程块(always_latch)

  • always_latch过程块表示过程块描述的是基于锁存器的逻辑
  • always_latch的推断敏感list的规则与always_comb相同,且在仿真0时刻也会执行一次

 

1.2.3.时序逻辑过程块(always_ff)

  • always_ff的敏感列表必须明确列出,一般为posedge或negedge

 

1.3.SV对任务和函数的改进

SV中task和function中若有多条语句,可以不用像verilog一样使用begin...end打包

verilog中函数通过赋值与函数名相同的变量来提供返回值。SV可以使用return关键词

SV可以通过return提前结束任务或函数

SV提供了显示声明void空函数的功能

SV中函数的形式参数增加了output和inout,可以传送调用函数产生的变化

 

  • 有output或inout参数的函数不能在以下情况中调用:

1.事件表达式。

2.使用过程持续赋值的表达式。 

3.不在过程语句中的表达式

  • 在可综合模块中可用空函数代替任务,除了不能包含事件控制,啥都能干
  • SV使用参数名传递参数值eg.result <= devide(.denomibator(b),.numerator(a)) //显示传递
  • verilog中函数必须至少有一个输入参数,SV中可以没有形式参数(input/output/inout)
  • SV中缺省方向的形式参数默认为input,且类型为logic,且可定义形参的缺省值
  • 形参可以是数组、结构体或联合体
  • 自动任务和函数可以通过使用ref取代input/output来达到引用参数的目的(共用存储区)
  • 使用ref的好处是,任务中该参数对变化敏感(因为不是只是复制单时刻的值)且可以立即传播变化
  • 有output/inout/ref参数的函数不能被以下情况中调用:

1.事件表达式。

2.使用过程持续赋值的表达式。 

3.不在过程语句中的表达式

4.持续赋值中的表达式

  • 当使用const ref声明形参时,任务和函数只能对参数进行只读操作
  • SV中使用endtask endfunction指明任务或函数结尾名称

 

二、过程语句(procedural statements)

 2.1.    新操作符

  • 递增/递减操作符(++/—) (属于阻塞赋值) (作为独立语句时可综合)
  • 后加:j=i++;//j=i,然后i+1.
  • 先加:j=++i;//i+1然后赋给j
  • 赋值操作符(+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=,<<<=,>>>=)(属于阻塞赋值,独立语句可综合,都是=左边作为主操作数,最后赋值给=左边)
  • 有无关通配符的相等操作符(==,===,==?)(右边操作数为常数时可综合)(==?中右边操作数中x/z看作通配符,与任意数值匹配)
  • 设置成员操作符(inside)eg.
if(a inside {3’b001,3’b010}); //即if((a==3’b001)||(a==3’b010));

 

2.2.    操作数改进

  • 增加类型强制转换符(’(expression))
  • 增加尺寸强制转换符(’(expression))
  • 增加符号强制转换符(’(expression).   ’(expression))

 

2.3.改进的for循环(可综合)

  • for循环内部声明(循环内定义的变量)的变量是自动变量(每个循环的内部循环变量互不影响)
  • 如果要在循环外饮用一个变量,该变量需在循环外声明。
  • 循环内的局部变量不能层次化引用,但是外部声明的变量可以层次化引用

 

2.4. 底部检测的do...while循环(静态确定循环次数时可综合)

  • while语句在循环开始检测循环控制;
  • do...while在在循环结尾检测,保证至少执行一次
  • 语法:    
do<语句或语句块>
While(<条件>);

 

2.5.foreach数组循环结构

  • 见4.4

 

2.6.新的跳转语句——break、continue、return(可综合)

  • verilog:task中使用disable语句使语句序列执行流跳转或作为返回语句
  • SV中跳转语句(break、continue、return)只对当前执行流有效
  • continue语句

跳转到循环的结尾然后重新回到开头执行循环控制

  • break语句

中止循环的执行(整个循环结束,彻底,完全,结束)

  • return语句

从非空函数返回或者从空函数或任务重跳出。

 

2.7. 改进的块名

begin:

  ...

end:

 

2.8. 语句标号(statement label)

begin:block1          //named block                                            

  ...

end : block1


block2:begin          //带label的块

  .....

end
  • 一个语句块不能同时有label和block name

 

2.9.改进的case语句

  • verilog中case语句默认带有优先级(由前至后)
  • SV为case,casez,casex的判定提供了修饰符unique和priority,均需指明所有条件
  • unique case等效于同时使用verilog中的full_case及parallel_case附注

该语句指定:必须有且只有一个条件选项与条件表达式匹配

unique case()

  ...//条件选项

endcase
  • priority case等效于verilog中的full_case附注

该语句指定:

至少有一个条件选项与条件表达式相符

若存在多个条件选项的值与条件表达式匹配,则必须执行第一个匹配分支

priority case()

  ...//条件选项

endcase

 

2.10.改进的if...else判断语句(可综合)

  • unique if...else

取消判断顺序优先级

  • priority if...else

表示分支的次序是重要的,需按照原有次序进行优先级编码

 

三、参考文献

  • Link:https://www.cnblogs.com/daisyuer/p/9199508.html

 

 

 

你可能感兴趣的:(SystemVerilog)