Domanda

I ran across the following constraint in a testbench. It's behavior seems to vary depending on the simulator used.

constraint wr_c {
    if (!one_beat) { addr[5:0] == 0, len == 15 };
}

What is it actually supposed to do, as written?

An example:

import uvm_pkg::*;

class pkt extends uvm_object;

  rand bit one_beat;
  rand int len;
  rand bit [31:0] addr;

  `uvm_object_utils_begin(pkt)
    `uvm_field_int(one_beat, UVM_DEFAULT)
    `uvm_field_int(len, UVM_DEFAULT)
    `uvm_field_int(addr, UVM_DEFAULT)
  `uvm_object_utils_end

  constraint wr_c {
    if (!one_beat) { addr[5:0] == 0, len == 15 };
  } 

endclass

module test;

  initial begin
    for (int i = 0; i < 10; i++) begin
      automatic pkt p = new();
      p.randomize();
      p.print();
    end
  end

endmodule
È stato utile?

Soluzione

The reason the different simulator give different results likely has to do with what it constitutes as true for the solver. Using the following example:

rand bit [1:0] example;
rand bit one_beat;
constraint example_c { if(!one_beat) example; }

In this case example has the same randomization width as { addr[5:0] == 0, len == 15 }. Depending on the simulator the above constraint may infer example==2'b1 or example!=2'b0 or example>2'b0 (different results with signed and unsigned) . If one_beat wasn't an one-bit value, the same issue would be true for want counts as true for the if() statement.

If the OR option is intended, a better way to write the constraint would be:

if (!one_beat) ( addr[5:0] == 0  ||  len == 15 );

or

if (!one_beat) { addr[5:0] == 0, len == 15 } != 0; // or '>0', '>=1', etc

There is a good change the creator of the constraint intended both constraints to be true when if(!one_beat). In this case the follow would be better constraint options:

if (!one_beat) { addr[5:0] == 0; len == 15; } // note the semicolon positions

or

if (!one_beat) ( addr[5:0] == 0 && len == 15 );

Also note that with the given SSCCE, one_beat has a very low probability of being 1'b0 because the solver is trying to find a legal condition for one_beat, addr and len in parallel with equal priority.

  • When addr[5:0]==0 || len==15 its probability is 1/(1+2**6) + 1/(1+2**32)
  • When addr[5:0]==0 && len==15 its probability is 1/(1+2**(6+32))

If this is not intend, then add another constraint such as one_beat dist { ... }; or sovle one_beat before addr,len;

Altri suggerimenti

This is how the constraint behaves on different simulators. The constraint behaves differently because the simulators treat the concatenation constraint {a, b}; in different ways.

The code below is pseudo code for purposes of demonstrating how the constraint from the question works.

On VCS 2013.06:

if (!one_beat) { 
  { addr[5:0] == 0, len == 15 } == 2'b01 || { addr[5:0] == 0, len == 15 } == 2'b10;
  // distribution highly favors 2'b01
}

On Questa SIM 10.1d:

if (!one_beat) { 
  { addr[5:0] == 0, len == 15 } == 2'b10;
}

On INCISIV 13.10.001:

if (!one_beat) { 
  { addr[5:0] == 0, len == 15 } == 2'b01 || { addr[5:0] == 0, len == 15 } == 2'b10;
  // distribution favors 2'b10
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top