概述
本章介绍一些SytemVerilog的新特性,它会使RTL设计更简洁高效。
新的操作符(New Operators)
SystemVerilog增加了一系列的新操作符,大部分借鉴于C语言。它们包括自加(++)和自减(–),赋值运算符(+=, -=, …)。通配比较运算(wild equality)符(===和!==)类似于在casex语句中,忽略X和Z的值。
新的循环声明(New loop statements)
同样来自于C语言,加入了do-while循环以及break和continue。新的foreach循环主要用于数组相关的操作。for循环得到了扩展,允许下面这样的操作。
for (int i = 15, logic j = 0; i > 0; i --, j = ~j) ...
标签(Labelling)
在Verilog中,你可以给begin和fork语句加标签:
begin : a_label
在SystemVerilog中,标签还可以加到end:
end : a_label
这有助于组织代码。在end处加的标签,必须和begin处的一致。模块,任务和函数也是这样。
module MyModule ...
...
endmodule : MyModule
在SystemVerilog中,任务进程化语句可以加标签:
loop: for (int i=0; ...
这对于for循环尤其有用,因为这样可以通过标签来中止循环。
宽松的赋值规则(Relaxed Assignment Rules)
对于刚接触Verilog的新人来说,搞清楚变量和线网之间的区别可能是最难的部分。SytemVerilog把这种困惑变成了历史:变量可以被进程语句赋值,连续复制以及接到模块的输出端口。唯一需要注意的是,你仍然不能把变量接到inout端口,虽然你可以用ref端口。
这意味着,在Verilog中,你有时会用reg,有时会用wire。而在SystemVerilog中,你大部分会用logic数据类型。
当然,这里还是有一些限制的。同一个变量不能被多个连续赋值语句赋值或者连接多个输出端口。这是因为变量不像线网一样,具备多驱动解析。当然,如果你用了连续赋值,就不能再用过程化语句赋值了。
简化端口连接(Port Connection Shorthand)
比如你在用Verilog-2001,写一个模块的TB,该模块有如下声明:
module Desgin (input Clock, Reset, input [7:0] Data, output [7:0] Q);
在TB中,可以这样声明变量和线网:
reg Clock, Reset;
reg [7:0] Data;
wire [7:0] Q;
你可能会这样例化模块:
Design DUT (Clock, Reset, Data, Q);
或者这样
Design DUT (.Clock(Clock), .Reset(Reset), .Data(Data), .Q(Q));
但是这样看起来有点冗余。SystemVerilog支持使用下面这种简写:
Design DUT (.Clock, .Reset, .Data, .Q);
相对于的变量和线网可以写成这样:
logic Clock, Reset;
logic [7:0] Data;
logic [7:0] Q;
如果继续简化,可以写成这样:
Design DUT (.*);
这代表,把所有的端口接到相同名字的线网或者变量。你可以选择性使用这样方式,比如:
Design DUT (.Clock(SysClock), .*);
这代表把Clock和SysClock接到一起,其余的按照相同名字连接。
综合习语(Idioms)
虽然Veilog不是为了综合设计的语言,但是它广泛应用于RTL综合。经常碰到的问题是,Verilog仿真正确,但是综合出了错误的网表。比如说,很容易综合出意想不到的锁存器。SystemVerilog通过引入新的always关键字:always_comb, always_latch, 和always_ff来解决这一问题。
always_comb用来描述组合逻辑。它会通过查询该进程中的变量和线网,从而隐式地创建一个完整的敏感事件列表,就像Verilog-2001中always @*。
always_comb
if (sel)
f = x;
else
f = y;
为了能自动创建完整的敏感事件列表, 它会递归查询函数主体以及插入任何有必要的信号到列表。根据定义,它会强制某些组合逻辑的规则,并且给综合工具一个标志,去使用更严格的综合风格检查。
always_latch和always_ff是用来推断出锁存器和触发器的。下面这个例子是always_ff:
always_ff @ (posedge clock iff reset == 0 or posedge reset)
if (reset)
q <= 0;
else if (enable)
q++;
用这些新的代码风格的好处是,综合工具可以检查代码是否符合设计意图。
唯一性和优先级(Unique and Priority)
另外一个Verilog常见的错误是,误用parallel_case和full_case编译指令。问题在于,上述编译指令会被仿真器忽略,却用于综合。SystemVerilog通过加入两个新的关键词unique和priority来解决。
和编译指令不同的是,这些关键字可以应用于if和case语句。每个应用到仿真器的行为,会被映射到综合后的硬件。unique会强制条件的完整性和唯一性,换句话说,在仿真过程中,只有一个分支起作用。如果存在没有分支或者多个分支起作用,会报仿真错误。比如说,在case语句中,可能会出现多个分支同时选中,如果前述交叠在仿真过程中发生,就会报错误。类似的,在unique case语句中,可以没有默认分支或者在if语句中没有else分支,但是仿真器还是会检查这些分支是否真的起作用。综合工具会用这些信息,而不是编译指令去推断网表。
priority强制的检查相对较少,检查至少有一个分支起作用。所以它允许多个条件同时起作用。它许可综合工具在这种情况下创建用于区分优先级的逻辑。
最后
以上就是唠叨朋友为你收集整理的SystemVerilog - RTL Design新的操作符(New Operators)新的循环声明(New loop statements)标签(Labelling)宽松的赋值规则(Relaxed Assignment Rules)简化端口连接(Port Connection Shorthand)综合习语(Idioms)唯一性和优先级(Unique and Priority)的全部内容,希望文章能够帮你解决SystemVerilog - RTL Design新的操作符(New Operators)新的循环声明(New loop statements)标签(Labelling)宽松的赋值规则(Relaxed Assignment Rules)简化端口连接(Port Connection Shorthand)综合习语(Idioms)唯一性和优先级(Unique and Priority)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复