对不同的地址范围使用蕴涵运算符

Using implication operator for different address ranges

我想知道如果我想在不同的地址范围之间进行选择,如何使用蕴涵运算符。我正在使用 if/else 条件,但约束求解器似乎不接受任何解决方案。

  constraint ctCopy { mode == C_CMD -> if      (addr_range == "DST_SRAM") {dstAddr inside {[0:'hFFFF]}; }
                                          else if (addr_range == "DST_AXI")  {dstAddr inside {['h30000:'h3FFFF]}; }
                                          else if (addr_range == "DST_AHB")  {dstAddr inside {[20000:'h2FFFF]}; }
                                          else                               {dstAddr inside {[0:'hFFFF]}; }
                      mode == C_CMD -> if      (addr_range == "SRC_SRAM") {srcAddr inside {[0:'hFFFF]}; }
                                          else if (addr_range == "SRC_AXI")  {srcAddr inside {[0:'h30000]}; }
                                          else                               {srcAddr inside {[0:'hFFFF]}; }
                      mode == C_CMD -> cSize inside {[2:10]} ;
                      }

我正在尝试使用 with 约束,但解算器不接受。这是片段:

  Trn0.randomize() with { mode == C_CMD; addr_range == "DST_AHB";};

重现的小例子如下

class top;
  rand logic [3:0] mode;
  rand logic [16:0] dstAddr;
  rand logic [16:0] srcAddr;
  string addr_range;
  rand logic [4:0] copySize;

  constraint ctCopy { mode == 1 -> if      (addr_range == "DST_SRAM") {dstAddr inside {[0:'hFFFF]}; }
                                       else if (addr_range == "DST_AXI")  {dstAddr inside {['h30000:'h3FFFF]}; }
                                       else if (addr_range == "DST_AHB")  {dstAddr inside {[20000:'h2FFFF]}; }
                                       else                               {dstAddr inside {[0:'hFFFF]}; }
                      mode == 1 -> if      (addr_range == "SRC_SRAM") {srcAddr inside {[0:'hFFFF]}; }
                                       else if (addr_range == "SRC_AXI")  {srcAddr inside {[0:'h30000]}; }
                                       else                               {srcAddr inside {[0:'hFFFF]}; }
                      mode == 1 -> copySize inside {[2:10]} ;
                      }
  
endclass

module tb;
  initial begin
    top tb = new;
    tb.randomize() with { mode == 1; addr_range == "DST_AHB";};
    $display("dstAddr=%0d,srcAddr=%0d",tb.dstAddr,tb.srcAddr);
  end
endmodule

自包含示例位于:

https://www.edaplayground.com/x/rjZy

addr_rangestring 类型,这意味着它不能是 rand 变量。解决问题的一种方法是在调用 randomize:

之前设置 addr_range
module tb;
  initial begin
    top tb = new;
    tb.addr_range = "DST_AHB";
    tb.randomize() with { mode == 1; };
    $display("dstAddr=%0d,srcAddr=%0d",tb.dstAddr,tb.srcAddr);
  end
endmodule

如果您希望 addr_range 是随机的,另一种方法是使用枚举而不是字符串。


当您在 edaplayground 上使用 Cadence 运行 时,它会生成有关约束中的某些值超出范围的警告消息。例如,您将 dstAddr 声明为 17 位值,但 'h3FFFF 至少需要 18 位。你应该修正你的价值观。