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
- Cover front and back padding for every line (sequence item fields)
- Cover sequences dimensions (sequence fields)
- Cover config fields of Active agent - which are randomized in the driver class
- 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!