Struggling to implement complex coverage

Hello,

I have a quite complex env for a large DUT which has 42 identical interfaces when 21 are inputs and 21 are outputs, that modules synchronizes clock domains and transfers data using FIFOs from input to output interface.

For every Input interface I create an Active agent which has a driver, sequencer, monitor and a config object.
and for Output interface I create a Passive agent which has a monitor and config object, in addition the monitor is driving a “ready” signal to the interface for the communication handshake mechanism.

A sequence is a frame sent through the interface, a sequence item is a line in that frame.

I want to build coverage for this project

  1. Cover front and back padding for every line (sequence item fields)
  2. Cover sequences dimensions (sequence fields)
  3. Cover config fields of Active agent - which are randomized in the driver class
  4. Cover config fields of Passive agent - which are randomized in the monitor class

Is there an option to perform all of that in one unified Coverage/Subscriber class?
Where is it best to place it in the hierarchy and how to connect and send all this data?
I thought to declare events like:
event sequence_created;
event frame_config_change;
event passive_agent_config_change;
and on every place in the code where sampling is needed to trigger that event with ->sequence_created for example.
Is that possible?

Hope I managed to explain clear enough I am pretty new with UVM and Coverage.

class inu_top_sync_unit__4500_coverage #(   parameter int PW = 24,
    parameter int IDW = 16) extends uvm_subscriber #(inu_ciif_sequence_item #(PW));
    
    `uvm_component_param_utils(inu_top_sync_unit__4500_coverage #(PW,IDW))
    
    typedef struct {int low, high;} range_t;

    //range_t range_arr[4] = {'{1,1278}, '{1282, 1918}, '{1922,3838}, '{3842,7678}};

    uvm_analysis_export     #(inu_ciif_sequence_item #(PW))   mon_analysis_export;
    uvm_tlm_analysis_fifo   #(inu_ciif_sequence_item #(PW))   req_f;      // line sampling
    inu_ciif_sequence_item  #(PW) req;  

    inu_ciif_config         #(IDW)                            ciif_cfg;   // config sampling

    event sequence_created;
    event frame_config_change;
    event passive_agent_config_change;
    
    // Sequence (Frame) fields
    int width;                  // Can I cover sequence item & config from the same coverage object??
    int height;

    // Sequence Item (Line) fields
    int front_line_blank;
    int back_line_blank;

    // CIIF config fields
    // Active agent
    int front_frame_blank;
    int back_frame_blank;
    int rate;

    // Passive agent
    int fixed_ready_ratio;

    //covergroup seq_cg(range_t range) @ (sequence_created);
    covergroup seq_cg @ (sequence_created);
        W : coverpoint width {         // Consider 8k as MAX 7680\u2009×\u20094320
            bins UHD_8k     = {7680};      // Reminder: Even values constraint
            bins UHD_4k     = {3840};
            bins FHD_1080p  = {1920};
            bins HD_720p   = {1280};
            //bins b = {[range.low: range.high]};
        }
        H : coverpoint height {
            bins UHD_8k     = {4320};      // Reminder: Even values constraint
            bins UHD_4k     = {2160};
            bins FHD_1080p  = {1080};
            bins HD_720p   = {720};
            //bins default;
        }
        res : cross W, H;
    endgroup


    // 1.  A covergroup with a bin for every operation (auto_bins)
    covergroup line_cg;
        // Line padding
        coverpoint front_line_blank {
            bins max = {1024};
            bins min = {0};
            bins mid = {[1:1023]};
        }
        coverpoint back_line_blank {
            bins max = {1024};
            bins min = {0};
            bins mid = {[1:1023]};
        }
    endgroup // line covergroup
   
    covergroup frame_cg @ (frame_config_change); // How to get all different agents' config. data?
        // Frame padding
        front_frame_porch: coverpoint front_frame_blank {
            bins max = {8};
            bins min = {0};
            bins mid = {[1:7]};
        }
        back_frame_porch: coverpoint back_frame_blank {
            bins max = {8};
            bins min = {0};
            bins mid = {[1:7]};
        }
        frame_porch: cross front_frame_porch, back_frame_porch;
    endgroup // frame covergroup
    
    covergroup passive_cg @ (passive_agent_config_change);
        // Passive Agent
        coverpoint fixed_ready_ratio {
            bins rand_ready     = {0};
            bins fixed_ready    = {[1:6]};
        }
    endgroup                         
                                     
    // Create                        
    function new(string name="cntr_c overage", uvm_component parent);
        super.new(name, parent);
        seq_cg      = new();
        line_cg     = new();                    //Instantiate groups
        frame_cg    = new();
        passive_cg  = new();
        req_f = new ("req_f", this);
    endfunction : new

    // Build
    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        if (!uvm_config_db #(inu_ciif_config #(IDW)) :: get (this, "", "ciif_cfg", ciif_cfg)) begin // get cfg from agent
            `uvm_fatal (get_type_name (), "Didn't get handle to config inu_ciif_config")
        end
    endfunction : build_phase
    

   virtual function void connect_phase( uvm_phase phase );

      super.connect_phase( phase );

      mon_analysis_export.connect(req_f.analysis_export );

   endfunction: connect_phase

   function void write(inu_ciif_sequence_item#(PW) r);
           
       req = r; 
       front_line_blank = req.front_line_blank;
       back_line_blank  = req.back_line_blank;
       line_cg.sample();
 
            //always @(sequence_created) begin : sample_seq
            //   SAMPLE
            //end : sample_seq
            //
            //always @(frame_config_change) begin : sample_frame
            //   
            //end : sample_frame
            //
            //always @(passive_agent_config_change) begin : sample_config
            //
            //end : sample_config
              

   endfunction: write


endclass : inu_top_sync_unit__4500_coverage

Code obviously not functional, just pasted to give some sense.

Thanks for any kind of assistance!