Pramod
Pramod

Reputation: 25

Using function inside constriant block

I am trying to use a function inside constraint block. Randomization happens but the constraints are not being met. I have verified that the function works as expected outside the constraint block. The function uses only function arguments and not any other class members.

local rand      logic [6:0] [3:0] [9:0] coeff_mult;

constraint prods_are_multiples {
     foreach(coeff_mult[i]) {
           get_real(coeff_mult[i][3]) == (-1 * get_real(coeff_mult[i][0]));
           get_real(coeff_mult[i][2]) == (-1 * get_real(coeff_mult[i][1]));
           get_real(coeff_mult[i][0]) == (3 * get_real(coeff_mult[i][1]));
     }
 }

 function automatic shortreal get_real(input [9:0] val);
                shortreal sign;
                bit [9:0] magnitude;
                sign = -1**(val[9]);
                magnitude = ({10{val[9]}} ^ val[9:0]) + val[9];
                get_real = sign * (magnitude[9:3] + magnitude[2] * 0.5 + magnitude[1] * 0.25 + magnitude[0] * 0.125);                
 endfunction

I came across a similar post, but it didnt solve my problem.

Is there anything wrong with the code? If not, is there any other way of doing this?

Upvotes: 0

Views: 703

Answers (2)

dave_59
dave_59

Reputation: 42698

The post you reference explains the reasoning. The inputs to your function get their random values chosen before calling the function in the constraint. So there are effectively no constraints on coeff_mult before evaluating the equality constraints.

Also, the LRM does not allow expressions of non-integral values in constraints, technically, although some tools allow limited cases.

The best strategy for randomizing real numbers is doing everything with scaled integral values, then converting the resulting values to real (or sign/magnitude) in post_randomize().

Upvotes: 4

Karan Shah
Karan Shah

Reputation: 1992

I have a working example of your kind of function usage with use of additional random variable. I have checked this with ~10 different seeds and I have also posted constraint results with 1 particular seed.

typedef bit [7:0] tabc;

class t;
  rand bit [3:0] a, b;
  rand tabc ca;

  // Original Constraint : get_b(b) == get_a(a) + 1;
  constraint c {
    ca == get_b(b);
    get_a(a) ==  ca - 1;
  }

  function tabc get_a (input bit[3:0] a);
    return (tabc'(a + 15));
  endfunction

  function tabc get_b (input bit[3:0] b);
    return (tabc'(b + 10));
  endfunction
endclass

program temp();
  t t1 = new();

  initial
  begin
    repeat (10) begin
      t1.randomize();
      $display("t1.a - %0d", t1.a);
      $display("t1.b - %0d", t1.b);
    end
  end
endprogram

// Results - 
t1.a - 7
t1.b - 13
t1.a - 2
t1.b - 8
t1.a - 5
t1.b - 11
t1.a - 4
t1.b - 10
t1.a - 0
t1.b - 6
t1.a - 8
t1.b - 14
t1.a - 9
t1.b - 15
t1.a - 6
t1.b - 12
t1.a - 0
t1.b - 6
t1.a - 5
t1.b - 11

I am not quite sure of how this one is different than your method. However I am thinking that without having any random variable in constraints, the solver might have considered as no constraint for any variable and hence it didn't try to solve constraint before the solution.

I tried to insert temporary variable, in order to force solver to look at constraints first.

I am not sure how much correct my explanation is, but atleast it worked for me for some time. You can check it and try to run it with more seeds, before adapting it into your solution.

Upvotes: 1

Related Questions