SystemVerilog中unique与priority
在Verilog中,代码不规范的case语句经常会导致意外的综合优化或意外的latch。如果未在硅前仿真或门级仿真中发现这些问题,则很容易导致芯片无法正常工作。SystemVerilog 拥有unique关键字和priority关键字,旨在解决上述问题。SystemVerilog中的unique和priority关键字修饰符放在if,case,casez,casex语句之前,如下所示:
unique if (expression) statements else statements priority case (case_expression) case_item_1: case_expression_1 case_item_2: case_expression_2 endcase如果使用了if...else语句时,SystemVerilog中unique和priority关键字仅放置在第一个if之前,但是会影响后续所有else if和else语句。
-
unique
使用case语句比较容易说明unique关键字,unique case则说明如果出现以下任意一种情况,都会导致报警:
1)存在多个case选项和case表达式相匹配。
2)不存在case选项和case表达式相匹配,并且没有default case选项。
为了说明SystemVerilog中unique如何影响case语句的仿真结果,我们看下通配符casez语句:
always @(irq) begin {int2, int1, int0} = 3'b000; unique casez (irq) 3'b1?? : int2 = 1'b1; 3'b?1? : int1 = 1'b1; 3'b??1 : int0 = 1'b1; endcase end当不使用unique时,则可能存在多个case语句满足表达式,此时存在优先级。当使用unique后,则设计者能够断定有且仅有一个case与case表达式相匹配,如果存在多个,则会发出警告。对于综合工具来说,使用unique后,则说明所有可能出现case情况都已经列举完毕,并且它们之间属于并行关系,综合工具将对未列举的case进行优化。
此外,综合时将消除优先级,导致逻辑更小,更快。
SystemVerilog中的unique还可用于if...else语句,以传达相同的唯一性属性,对于含有unique的if语句,如果下述情况存在,则模拟器在运行时就会发出警告:
1)存在多个if条件为真的
2)所有的if条件(包括else if)均为假,并且没有最终的else分支在2012版SystemVerilog中,添加了关键字unique0,只针对上述第1种情况发出警告。
module unique_if; //variables declaration int a,b,c; initial begin //initialization a=10; b=20; c=40; unique if ( a < b ) $display("\t a is less than b"); else if ( a < c ) $display("\t a is less than c"); else $display("\t a is greater than b and c"); end endmodule仿真结果如图所示:
module unique_if; //variables declaration int a,b,c; initial begin //initialization a=50; b=20; c=40; unique if ( a < b ) $display("\t [unique] a is less than b"); else if ( a < c ) $display("\t [unique] a is less than c"); end initial begin //initialization a=50; b=20; c=40; unique0 if ( a < b ) $display("\t [unique0] a is less than b"); else if ( a < c ) $display("\t [unique0] a is less than c"); end endmodule仿真结果可看出,unique0的语句不再发出警告:
-
priority
priority if则会在所有的if...else if都不满足条件,并且最后也没有else语句的情况下发出警告。
module priority_if; //variables declaration int a,b,c; initial begin //initialization a=50; b=20; c=40; priority if ( a < b ) $display("\t [priority] a is less than b"); else if ( a < c ) $display("\t [priority] a is less than c"); end initial begin //initialization a=50; b=20; c=40; if ( a < b ) $display("\t a is less than b"); else if ( a < c ) $display("\t a is less than c"); end endmodule仿真结果如图所示:
那么在什么时候使用上述关键字呢?当明确知道存在优先级或者不存在优先级逻辑的情况下,应当使用SystemVerilog中的priority和unique关键字。使用这些关键字有利于传达设计意图,指导综合工具获得正确的结果。但是使用上述关键字并不能保证删除不必要的latch。在case语句中,如果存在case选项丢失,则仍然可能存在latch,避免这些latch的最简单的方式是在case语句之前对输出值进行默认分配。
但是,也不能盲目添加上述关键字,下述例子就是导致设计出现问题。预期结果时当en=0时,输出为4'b0000。
但是,也不能盲目添加上述关键字,下述例子就是导致设计出现问题。预期结果时当en=0时,输出为4'b0000。
logic [3:0] y; logic [1:0] a; logic en; always_comb begin y = '0; priority case ({en,a}) 3'b100: y[a] = 1'b1; 3'b101: y[a] = 1'b1; 3'b110: y[a] = 1'b1; 3'b111: y[a] = 1'b1; endcase end逻辑综合结果为:
这里的priority关键字表示所有未列出的案例都是无关紧要的,可以进行优化。结果,综合工具将只优化en,从而导致硬件与预期的硬件不同。当en = 0时,模拟器将报告警告,警告某些错误。
-
总结