SystemVerilog Class Print Delay Issue

Hi all,

Just came across this one minor issue that I wanted to know what I can do about it.
The prompt that I was trying to make was that given two tests scores (all less than or equal to 100), I created a child class from that class where my code looked something like this for the setting up of the classes.

/*-----CLASSES-----*/
class the_tests;
  rand bit [6:0] test1;
  rand bit [6:0] test2;

  constraint limit_score {test1 <= 100;
                          test2 <= 100;};    

endclass :  the_tests
 
// used for categorical constraints
typedef enum {F, D, C, B, A} grade; 

// child class 
class myGrade extends the_tests; 
  rand grade grade_type; 
  bit [6:0] average; 

  function int get_average();
    average = ((test1 + test2)/2);
    return average;

  endfunction


  constraint grade_range 
  {
    (grade_type == F) -> average inside {[0:50]};        
    (grade_type == D) -> average inside {[51:60]};      
    (grade_type == C) -> average inside {[60:79]};      
    (grade_type == B) -> average inside {[80:89]};        
    (grade_type == A) -> average inside {[90:100]};      

  }

endclass  : myGrade

But in my initial block, I used the following code:

initial begin
  myGrade students;
  students = new; 
  
  repeat(10) begin
    if(students.randomize() == 1)
      begin
      $display("First Test = %d Second Test = %d   Final Score: %0d   Final Grade: %s\n", students.test1, students.test2, students.get_average(), students.grade_type.name());
      end

    else
      $display("RANDOMIZATION FAILED \n");
  
  end

  $finish; 
end

This thus gave me correct results except for printing out Final Grade. The following are my results.

First Test = 37 Second Test = 28 Final Score: 32 Final Grade: F

First Test = 90 Second Test = 73 Final Score: 81 Final Grade: F

First Test = 25 Second Test = 65 Final Score: 45 Final Grade: B

First Test = 15 Second Test = 59 Final Score: 37 Final Grade: F

First Test = 40 Second Test = 22 Final Score: 31 Final Grade: F

First Test = 68 Second Test = 2 Final Score: 35 Final Grade: F

First Test = 42 Second Test = 71 Final Score: 56 Final Grade: F

First Test = 67 Second Test = 83 Final Score: 75 Final Grade: D

First Test = 14 Second Test = 48 Final Score: 31 Final Grade: C

First Test = 89 Second Test = 29 Final Score: 59 Final Grade: F

It seems to me that the FInal Grade is displaying based on the previous Final Score, so is there any way I could perhaps match that displaying of Final Grade correctly to its respective final score?

Sorry for the long read.

Sangwoo

You are not calculating the average at the correct time. “average” is not a random variable. The first time you execute randomize, average=0 because that is the default value for the “bit” type. average is updated to a new value only when you call the $display task. Therefore, its value is the old value.

Here is a different way to write your code which gives you the expected grades:

class myGrade extends the_tests;
  grade grade_type;
  bit [6:0] average;

  function int get_average();
    average = ((test1 + test2)/2);
    return average;
  endfunction

function void post_randomize;
    void'(get_average());
    case (average) inside
        [0:50]:   grade_type = F;
        [51:60]:  grade_type = D;
        [61:79]:  grade_type = C;
        [80:89]:  grade_type = B;
        [90:100]: grade_type = A;
    endcase
endfunction
endclass  : myGrade

module tb;
initial begin
  myGrade students;
  students = new;

  repeat (10) begin
    if (students.randomize() == 1) begin
      $display("First Test = %d Second Test = %d   Final Score: %0d   Final Grade: %s",
        students.test1, students.test2, students.average, students.grade_type.name());
    end
    else
      $display("RANDOMIZATION FAILED \n");
  end
  $finish;
end
endmodule

My random output:

First Test =  80 Second Test =   8   Final Score: 44   Final Grade: F
First Test =  35 Second Test =  48   Final Score: 41   Final Grade: F
First Test =  37 Second Test =  62   Final Score: 49   Final Grade: F
First Test =  71 Second Test =  69   Final Score: 70   Final Grade: C
First Test =  28 Second Test =  20   Final Score: 24   Final Grade: F
First Test =  14 Second Test =  99   Final Score: 56   Final Grade: D
First Test =  46 Second Test =  33   Final Score: 39   Final Grade: F
First Test =  94 Second Test =  11   Final Score: 52   Final Grade: D
First Test =  80 Second Test =  67   Final Score: 73   Final Grade: C
First Test =  72 Second Test =  97   Final Score: 84   Final Grade: B
1 Like

That actually worked, thanks!

Another question - is it possible to show how many people got each grade? For example, print out how many people got A’s or B’s…

I tried to print, but it only gives 0’s