Emman
Emman

Reputation: 1244

Using implication operator for different address ranges

I am wondering how implication operator can be used if I want to choose between different address ranges. I am using if/else condition, but it seems constraint solver is not accepting any solution for this.

  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]} ;
                      }

I am trying to use with constraint, but solver does not accept. Here is the snippet:

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

small example to reproduce is as below

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

Self contained example at:

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

Upvotes: 1

Views: 273

Answers (1)

toolic
toolic

Reputation: 62236

addr_range is of type string, which means it can not be a rand variable. One way to fix your problem is to set addr_range before you call randomize:

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

Another way is to use enums instead of strings if you want addr_range to be random.


When you run with Cadence on edaplayground, it generates warning messages about some of the values in your constraint being out of range. For example, you declared dstAddr as a 17-bit value, but 'h3FFFF requires at least 18 bits. You should fix your values.

Upvotes: 0

Related Questions