timesimulationsystem-verilogregression-testingbaud-rate

Difference between 1e12 and 1000000000000 in SystemVerilog


I'm trying to calculate the baud rate of the data transaction by capturing the simulation time of two signal changes. I couldn't get the correct baud rate computed until I changed the 1000000000000 to 1e12 for the numerator of the division:

(produced wrong baud rate, baud rate = 411)

measured_baud_rate = (1000000000000)/(duration);

(produced correct baud rate, baud rate = 115207)

measured_baud_rate = (1e12)/(duration);

This is very strange to me as I see them representing the same number, just different format. Why 1e12 produces the correct result? Below shows the more complete version of my code.

longint unsigned start_time;
longint unsigned stop_time;
longint unsigned duration;
real measured_baud_rate;

// Get simulation time of the first signal change.
start_time = $time;
`uvm_info(get_type_name(), $sformatf("Start time: %d ps", start_time), UVM_NONE)

// Wait for next signal change.
wait (previous_tsr_value != sim_top.tb.uart_inst.uart_0._uart_0.uart_tx.tx_shift_register_contents_out);

stop_time = $stime; // Get simulation time of the second signal change.
`uvm_info(get_type_name(), $sformatf("Stop time: %d ps", stop_time), UVM_NONE)

// Calculate the period between two signal changes.
duration = ($stime - start_time);
`uvm_info(get_type_name(), $sformatf("Duration: %d ps", duration), UVM_NONE)

// Baud rate calculation, how many bits can be transferred in one second.
// Duration is in picoseconds, so 1 second = 1000000000000 ps.
measured_baud_rate = (1000000000000)/(duration);
// measured_baud_rate = (1e12)/(duration);

`uvm_info(get_type_name(), $sformatf("Measured baud rate: %f", measured_baud_rate), UVM_NONE)

Results: When I use 1000000000000: enter image description here

When I use 1e12: enter image description here


Solution

  • You should have received the error along the lines of

    Unsized literal value 1000000000000 exceeds default size of literals which is 32-bit. Either size the literal (i.e. 64'd1000000000000) or reduce the literal value to fit in 32 bits.

    because all simple numeric literals are treated as decimal, signed 32-bit quantities.

    Also, since duration is a longint, (64.d1000000000000)/(duration) would computed as an integral division. You can use a real number 1000000000000.0. But isn't 1e12 easier to read? And why not use reals for everything, and don't use $stime. use $realtime instead. Otherwise you loose fractional time units.