Part 3 · Factory & Configuration · Intermediate
Liskov Substitution Safety: Override Classes That Actually Fit
Structural contracts for override derivatives, port/parameter compatibility, behavioral specialization boundaries, and connect_phase safety.
Substitution contract
An override class must be a true subtype of the requested base: same parameters, same public ports, compatible behavior . Factory substitution does not relax connect-time or TLM contracts.
[FACTORY][UVM] Liskov checklist for override class B replacing A
inheritance:
class B extends A (required)
structure:
same #(T) params on uvm_driver/uvm_agent generics
no removed uvm_*_port / export / imp members
behavior:
specialize run/body tasks, not connection topology
honor base handshake expectationsclass err_driver extends base_driver;
`uvm_component_utils(err_driver)
task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
if (req.inject_err)
drive_error(req);
else
drive_item(req);
seq_item_port.item_done();
end
endtask
endclassKey takeaways
Override classes extend base — never parallel unrelated classes.
Keep TLM topology stable so env connect_phase remains unchanged.
Specialize behavior, not structural role or interface surface.
Common pitfalls
Derivative drops a port used by env connect_phase.
Changing parameter types so analysis port write signatures mismatch.
Throwing new errors in derivative for valid base sequences.
Structural and behavioral review
Review override classes as API contracts, not just behavior tweaks.
Structural review matrix
Same sequence item type on driver/sequencer path.
Same analysis transaction type on monitor subscribers.
Config object handles still consumed via config_db as expected.
class verbose_monitor extends base_monitor;
`uvm_component_utils(verbose_monitor)
task run_phase(uvm_phase phase);
forever begin
@(posedge vif.clk);
collect_packet();
`uvm_info("PKT", pkt.sprint(), UVM_HIGH)
ap.write(pkt); // same analysis path as base
end
endtask
endclassBehavioral boundaries
[FACTORY] allowed vs risky specialization
allowed:
inject protocol errors under cfg control
add non-invasive logging/metrics
alter timing within protocol legal bounds
risky:
reject/legalize different transaction classes
change reset/phase assumptions of env
consume transactions without item_done/handshake completionfunction void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
assert (env.agt_tx.drv.seq_item_port != null);
assert (env.agt_tx.mon.ap != null);
endfunctionCommon pitfalls
Override class requiring new connect_phase wiring in env.
Changing randomization constraints that invalidate base sequences.
Using override to bypass protocol checks instead of extend them.