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

unique关键字告诉所有支持SystemVerilog的软件,包括仿真,综合,形式验证等软件,在一系列条件选项中,有且仅有一项是符合条件的。换句话说,所有的选项都是互斥的,并且if...else或者case语句指定了所有的有效选项,不存在遗漏。
使用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表示设计者认为存在多个case语句的值与表达式相匹配,并且条件选项的顺序十分重要,当不存在任意一项满足表达式的值时,仿真器会发出警告。
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。
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。但是此关键字不但减少了软件之间的不一致性,而且提供了进一步的语法检查,能够在设计周期的早期就发现设计存在的潜在问题。



全部评论
果然是大神,膜拜
点赞 回复 分享
发布于 2022-08-24 08:47 江苏

相关推荐

我见java多妩媚:大外包
点赞 评论 收藏
分享
评论
点赞
1
分享
牛客网
牛客企业服务