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

class fact_fifo extends uvm_tlm_fifo#(int);
  int configured_value;
  int apply_calls;
  `uvm_component_utils_begin(fact_fifo)
    `uvm_field_int(configured_value, UVM_DEFAULT)
  `uvm_component_utils_end
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction
  virtual function void apply_config_settings(bit verbose = 0);
    apply_calls++;
    super.apply_config_settings(verbose);
  endfunction
`ifdef REVIEW_FIFO_RESTORE
  virtual function bit use_automatic_config();
    return 1;
  endfunction
`endif
endclass

class fact_sequence extends uvm_sequence#(uvm_sequence_item);
  bit ready;
  function new(string name="seq"); super.new(name); endfunction
  function int pending_responses(); return response_queue.size(); endfunction
  task body();
    uvm_sequence_item response = new("response");
    put_response(response);
    ready = 1;
    wait (0);
  endtask
endclass

class fact_test extends uvm_test;
  `uvm_component_utils(fact_test)
  fact_fifo fifo;
  uvm_sequencer#(uvm_sequence_item) seqr;
  function new(string name="fact_test", uvm_component parent=null);
    super.new(name, parent);
  endfunction
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    uvm_config_db#(uvm_bitstream_t)::set(this, "fifo", "configured_value", 42);
    fifo = new("fifo", this);
    seqr = new("seqr", this);
  endfunction
  task run_phase(uvm_phase phase);
    fact_sequence seq = new();
    phase.raise_objection(this);
    $display("REVIEW|fifo_apply_calls|%0d", fifo.apply_calls);
    $display("REVIEW|fifo_configured_value|%0d", fifo.configured_value);
    fork seq.start(seqr); join_none
    wait(seq.ready);
    $display("REVIEW|responses_before_kill|%0d", seq.pending_responses());
    seq.kill();
    $display("REVIEW|sequence_stopped|%0d", seq.get_sequence_state() == UVM_STOPPED);
    $display("REVIEW|responses_after_kill|%0d", seq.pending_responses());
    seq.clear_response_queue();
    $display("REVIEW|responses_after_clear|%0d", seq.pending_responses());
    $display("REVIEW|done|1");
    phase.drop_objection(this);
  endtask
endclass

module doc_fact_probe;
  initial run_test("fact_test");
endmodule
