Wrong result of div

I have the following member of in_trx class:

       bit signed [15:0]  rand_data_xi;
       logic [3:0] fact_log_2;

And the followinf var:

       bit signed [15:0] xi_prev  = 0;
       bit signed [15:0] yi_prev = 0;

I do the following operation:

      real ci_n =  (in_trx.rand_data_xi - xi_prev)/ (2 ** in_trx.fact_log_2);
      predicted.xi = yi_prev +  int'(ci_n);

For the following input:

in_trx.rand_data_xi = 16'hFFEE
xi_prev = 0
in_trx.fact_log_2 = 4

I get:

 ci_n =  4094

Instead of:

 ci_n =-1.125

I asume that in_trx.rand_data_xi give for some reason unsigned instead of signed.

Why?

In reply to saritr:

Please review chapter 11 of the SystemVerilog LRM.

Per the LRM, if all of the operands are integral, then the result is integral. Even though ci_n is declared as real, all of the operands in the statement (rand_data_xi, xi_prev and fact_log_2) are integrals, resulting in the (correct) integral result of -1 instead of the real result -1.125.

In reply to cgales:

But it returns 4096, not -1.

In reply to saritr:

test.sv:


module test;

  bit signed [15:0]  rand_data_xi;
  logic [3:0] fact_log_2;

  bit signed [15:0] xi_prev  = 0;
  bit signed [15:0] yi_prev = 0;

  real ci_n;

  initial begin
    rand_data_xi = 16'hFFEE;
    xi_prev = 0;
    fact_log_2 = 4;
    ci_n =  (rand_data_xi - xi_prev) / (2 ** fact_log_2);
    $display("rand_data_xi = ", rand_data_xi);
    $display("2 ** fact_log_2 = ", 2 ** fact_log_2);
    $display("ci_n = ", ci_n);
  end

endmodule

qverilog test.sv:

rand_data_xi = -18

2 ** fact_log_2 = 16

ci_n = -1

In reply to saritr:

You must cast the integral portions to real (or shortreal) to get the desired outcome.

ci_n =  real'(rand_data_xi - xi_prev) / real'(2 ** fact_log_2);