Constraining an Object's Object's Variable

Hello,

I’m having an issue with my constraints in my testbench… I want part of a register to never be a certain value after a randomize function, so my code is similar to the following:


class B;
  extern void function run_main();
  logic myLogic1[15:0];
endclass
function B::run_main();
  if(!randomize())
    uvm_fatal("run_main","Randomization failure");
  else
    print("myLogic1 = %b", myLogic1);
endfunction
class A;
  extern void function run_main();
  B myB;
  constraint myLogic1_const;
endclass
constraint A::myLogic1_const{
  myB.myLogic1[15:14] != 2'b01;
}
function A::run_main();
  myB.run_main();
endfunction

Basically, I have a constraint in class A that is not being applied to class B, and the randomization function is not failing. Could this sort of constraint work? If not, how can you constrain one object’s variable from another object?

In reply to dsherman0623:

That should be


logic[15:0] myLogic1;
if(!randomize(myLogic1))  `uvm_error(.. 
.. 
constraint A::myLogic1_const{
  myB.myLogic1[15:14] != 2'b01;} 

 [/systemverilog ] 
Did your code really passed the compiler? 
Ben systemverilog.us

In reply to ben@SystemVerilog.us:

Good catch. The original code that has the correct syntax, I just didn’t want to post it up here. Do you know if this should work?

In reply to dsherman0623:
Is that code in a module?
My first impression is that the code is disorganized, I. E., not well structured.
This creates code that is hard to understand. Why don’t you use extended classes?
Ben systemverilog.us

In reply to ben@SystemVerilog.us:

I understand that extending class B and adding the constraint would create one solution to the problem. The reason I added code to the original post was to help illustrate the primary question I have:
If class A instantiates class B and puts a constraint on that instantiation’s members, will that constraint be applied if that object calls “randomize”.

In reply to dsherman0623:

It sounds like the B constraint should apply.
This may sound trivial & not scientific, but one way to find out is to try a test code.
True, not all vendors implement 1800 to the T, but they come close.
https://www.edaplayground.com allows you to try different vendors, and if they all give you the same answer, then they most likely are compliant to 1800.
Anyway, a quick way to get the answer (without even asking).
Another alternative, dig into 1800 lrm :)
Ben systemverilog.us

In reply to ben@SystemVerilog.us:

When you call randomize() inside a class method, there is an implied _this._randomize(). Only the constraints that are part of this object get used, in your case, the B object. The constraints in A are not seen. You need to either extend class B, or declare myB as rand and call randomize from A.

In reply to dave_59:

Just the kind of answer I was looking for. Thank you!