在Verilog中,代码不规范的case语句经常会导致意外的综合优化或意外的latch。如果未在硅前仿真或门级仿真中发现这些问题,则很容易导致芯片无法正常工作。SystemVerilog 拥有unique关键字和priority关键字,旨在解决上述问题。
SystemVerilog中的unique和priority关键字修饰符放在if,case,casez,casex语句之前,如下所示:
代码语言:javascript复制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
unique关键字告诉所有支持SystemVerilog的软件,包括仿真,综合,形式验证等软件,在一系列条件选项中,有且仅有一项是符合条件的。换句话说,所有的选项都是互斥的,并且if...else或者case语句指定了所有的有效选项,不存在遗漏。
使用case语句比较容易说明unique关键字,unique case则说明如果出现以下任意一种情况,都会导致报警:
1)存在多个case选项和case表达式相匹配。
2)不存在case选项和case表达式相匹配,并且没有default case选项。
为了说明SystemVerilog中unique如何影响case语句的仿真结果,我们看下通配符casez语句:
代码语言:javascript复制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种情况发出警告。
代码语言:javascript复制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
仿真结果如图所示:
代码语言:javascript复制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表示设计者认为存在多个case语句的值与表达式相匹配,并且条件选项的顺序十分重要,当不存在任意一项满足表达式的值时,仿真器会发出警告。
priority if则会在所有的if...else if都不满足条件,并且最后也没有else语句的情况下发出警告。
代码语言:javascript复制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。
代码语言:javascript复制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时,模拟器将报告警告,警告某些错误。
- 总结
对于综合,unique case相当于同时使用full_case和parallel_case附注;priority case等效使用full_case。但是此关键字不但减少了软件之间的不一致性,而且提供了进一步的语法检查,能够在设计周期的早期就发现设计存在的潜在问题。