SystemVerilog对Verilog兼容,就像C++兼容C一样,前者是后者的超集。
目录
一、基本数据类型的改进
1.1SV对表示数字的语法改进
二、SV对设计意图的关键字细化
三、void函数
四、循环语句性能增强
五、隐含的端口连接
六、SV模块的接口
一、基本数据类型的改进
相对于Verilog来说,SystemVerilog引进了一些新的数据类型,它们具有如下优点:
(1)双状态数据类型:更好的性能,更低的内存消耗。
(2)队列、动态和关联数组:减少内存消耗,自带搜索和分类功能。
(3)类和结构:支持抽象数据结构。
(4)联合和合并结构:允许对同一数据有多种视图(view)。
(5)字符串:支持内建的字符序列。
(6)枚举类型:方便代码编写,增加可读性。
更多数据类型介绍,请参考其他博客内容:
【SystemVerilog】数据类型(1)logic
【SystemVerilog】数据类型(2)定宽数组和动态数组
【SystemVerilog】数据类型(3)数组的方法
【SystemVerilog】数据类型(4)队列、枚举
- SV使用logic来替代reg/wire ,不必再纠结使用reg/wire的烦恼;
- SV新增2-state数据类型: bit/int/byte/ ; 双状态,即 0 / 1 ;而verilog中reg/wire都是四状态: 0 /1 /X /Z;
1.1SV对表示数字的语法改进
SystemVerilog | Verilog |
‘x | ‘bx |
‘z | ‘bz |
‘0 | ‘b0 |
‘1 | -1(-1的二进制补码,所有位为1) |
二、SV对设计意图的关键字细化
always关键字的细化
Verilog | SystemVerilog | |
always | always_comb | 组合逻辑 |
always_latch | 锁存器 | |
always_ff | 时序逻辑 | |
SV允许仿真工具进行某些语法功能检查,当生成电路与设计意图不符时将报错 |
unique/priority
unique case | 相当于使用full_case + parallel_case 即:必须有且只有一个条件选项与条件表达式匹配。 |
priority case | 相当于verilog中的full_case编译选项 即:至少有一个条件选项与条件表达式相符; 若存在多个条件选项的值与条件表达式匹配,则必须执行第一个匹配分支。 |
unique if..else | 取消判断顺序优先级 |
priority if..else | 表示分支的次序是重要的,需按照原有次序进行优先级编码 |
注:关于full_case及parallel_case的综合编译选项,其实是对代码书写不规范而做的一种约束,如果我们代码书写规范(如:使用default来生成完备的case)就不需要考虑full_case及parallel_case。徒增烦恼罢了。
更多详细内容请参考博文:
【SystemVerilog】SV对设计意图的细化always和unique/priority
三、void函数
回顾下verilog中的函数及任务:函数有输入,有返回值,不能有延时,不能调用任务;任务可以调用函数。那么如果想调用任务怎么办呢?SV提供了void函数,可以将无延时的任务改写为void函数进行调用。
void函数:
不能等待;
不能包括延时;
不能包括事件触发;
被always_comb搜索到的信号自动加入敏感列表。
举个栗子:
always_comb
orf1(a);
function void orf1;
input a;
y = a | b | c;
endfunction
四、循环语句性能增强
verilog中的循环语句:
integer i ;
for(i=0;i<10;i=i+1)begin : for_loop
//...
end
SV提供了 for/foreach/ do..while
for
for(int i =0;i< MAX;i++)
变量i在循环范围内有效,增加了++操作符代替i=i+1显示增加;
foreach
foreach(array[j])
$display(array[j]);
遍历数组,变量j自动声明,且只在循环范围内有效;
do..while
do
a++;
while (a>MAX);
foreach/do...while更多介绍及示例请参考上述数据类型博文。
五、隐含的端口连接
verilog的端口信号连接:
端口名连接
mod_a m1 ( .clk(clk) , rst(rst),.a(a));
顺序连接
mod_a m1(clk,rst,a);
SV新增的隐含的端口连接:(端口名必须相同)
.name
mod_a m1(.a, .clk, .rst);
.*
mod_a m1(.*);
需要注意的是:
- 在同一个实例中禁止混用 .name 与 .* ;
- 在同一个实例中可以同时使用.name 和 .name(signal) ;
- 在同一个实例中可以同时使用.* 和 .name(signal) ;
- 必须用.name(signal)的情况
- 位宽不匹配 : .a ( a[9:0]) ;
- 名称不匹配 : .a ( b ) ;
- 没有连接项 : .a ( ) ;
也就是说,我们使用SV进行端口信号连接时,只需要列出端口连接例外的情况即可:
mod_a m1( .* , .a ( b ) );
六、SV模块的接口
SV使用接口对于verilog上百端口信号连接来说也就方便了10086倍吧~
这个后续单独介绍。
参考资料 : 《绿皮书》 《systemverilog讲座》