SystemVerilog中unique与priority

2020-06-30 16:17:50 浏览数 (1)

在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。但是此关键字不但减少了软件之间的不一致性,而且提供了进一步的语法检查,能够在设计周期的早期就发现设计存在的潜在问题。

0 人点赞