`timescale 1ns/1ps
`include "uvm_macros.svh"
import uvm_pkg::*;
`ifdef REVIEW_UVM20
import uvm_compat_pkg::*;
`endif

class field_packet extends uvm_object;
  int value = 96;
  `uvm_object_utils_begin(field_packet)
    `uvm_field_int(value, UVM_NOCOPY)
  `uvm_object_utils_end
  function new(string name="field_packet"); super.new(name); endfunction
endclass

class old_automation extends uvm_object;
  int calls;
  function new(string name="old_automation"); super.new(name); endfunction
  virtual function void __m_uvm_field_automation(uvm_object tmp_data__,
`ifdef REVIEW_UVM20
                                               uvm_field_flag_t what__,
`else
                                               int what__,
`endif
                                               string str__);
    if (what__ == UVM_COPY) calls++;
  endfunction
endclass

class migrated_automation extends uvm_object;
  int calls;
  function new(string name="migrated_automation"); super.new(name); endfunction
  virtual function void do_copy(uvm_object rhs); calls++; endfunction
endclass

class field_printer extends uvm_table_printer;
  int calls, observed_size;
  uvm_radix_enum observed_radix;
  virtual function void print_field(string name, uvm_bitstream_t value, int size,
    uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name="");
    calls++; observed_size=size; observed_radix=radix;
  endfunction
  virtual function void print_field_int(string name, uvm_integral_t value, int size,
    uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name="");
    calls++; observed_size=size; observed_radix=radix;
  endfunction
endclass

class field_recorder extends uvm_text_recorder;
  int calls;
  function new(string name="field_recorder"); super.new(name); endfunction
  protected virtual function void do_record_field(string name, uvm_bitstream_t value,
                                                  int size, uvm_radix_enum radix);
    if (name == "value") calls++;
  endfunction
  protected virtual function void do_record_field_int(string name, uvm_integral_t value,
                                                      int size, uvm_radix_enum radix);
    if (name == "value") calls++;
  endfunction
endclass

module field_probe;
  initial begin
    field_packet packet = new();
    field_printer printer = new();
    field_recorder recorder = new();
    uvm_text_tr_database db = new("db");
    uvm_tr_stream tr_stream;
    old_automation old_a = new(), old_b = new();
    migrated_automation new_a = new(), new_b = new();
`ifdef REVIEW_UVM20
    uvm_compat_packer packer = new();
`else
    uvm_packer packer = new();
`endif
    bit bits[];
    int count, value = 96;
    #1;
    uvm_default_printer = printer;
    `uvm_print_int(value, UVM_HEX)
    $display("REVIEW|old_macro_size|%0d", printer.observed_size);
    $display("REVIEW|old_macro_hex|%0d", printer.observed_radix == UVM_HEX);
`ifdef REVIEW_UVM20
    `uvm_print_int(value, $bits(value), UVM_HEX)
`else
    `uvm_print_int(value, UVM_HEX)
`endif
    $display("REVIEW|migrated_macro_size|%0d", printer.observed_size);
    $display("REVIEW|migrated_macro_hex|%0d", printer.observed_radix == UVM_HEX);
    printer.calls=0;
    void'(packet.sprint(printer));
    $display("REVIEW|negative_print_calls|%0d", printer.calls);
    count = packet.pack(bits, packer);
    $display("REVIEW|negative_pack_bits|%0d", count);
    tr_stream = db.open_stream("stream", "scope", "type");
    recorder.m_do_open(tr_stream, 0, "type");
    packet.record(recorder);
    $display("REVIEW|negative_record_calls|%0d", recorder.calls);
    recorder.close();
    old_a.copy(old_b);
    new_a.copy(new_b);
    $display("REVIEW|old_automation_calls|%0d", old_a.calls);
    $display("REVIEW|migrated_automation_calls|%0d", new_a.calls);
    $display("REVIEW|done|1");
    $finish;
  end
endmodule
